2016-08-03 106 views
0

我遇到了kernal32 Pinvoke函數的問題,因爲它們會一直拋出INVALID_FILE_HANDLE。該程序讀取當前硬盤的第一個扇區。我看不到以下代碼有什麼問題。C#拼寫無效的文件句柄

class Program 
    { 
    const uint GENERIC_READ = 0x80000000; 
    const uint FILE_SHARE_READ = 0x00000001; 
    const uint OPEN_EXISTING = 0x00000003; 
    const uint FILE_FLAG_DELETE_ON_CLOSE = 0x04000000; 

    [DllImport("kernel32.dll", SetLastError = true)] 
    public static extern SafeFileHandle CreateFile(string Disk, uint Access, uint ShareMode, IntPtr SecurityAttributes, uint CreationDisposition, uint Flags, IntPtr TemplateFile); 
    [DllImport("kernel32.dll", SetLastError = true)] 
    public static extern uint SetFilePointer([In] SafeFileHandle Handle, [In] int DistanceToMove, [Out] out int DistanceToMoveHigh, [In] int MoveMethod); 
    [DllImport("kernel32.dll", SetLastError = true)] 
    unsafe public static extern int ReadFile(SafeFileHandle Handle, [Out] byte[] Buffer, int NumberOfBytesToRead, out int NumberOfBytesRead, IntPtr Overlapped); 



    unsafe public static void Main(string[] args) 
    { 
     string Drive = @"\\.\C"; 
     int SectorSize = 512; 
     int Sector = 0; 
     int BytesRead, DistanceToMoveHigh; 
     byte[] Buffer = new byte[SectorSize]; 

     SafeFileHandle Handle = CreateFile(Drive, GENERIC_READ, FILE_SHARE_READ, IntPtr.Zero, OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, IntPtr.Zero); 
     SetFilePointer(Handle, Sector * SectorSize, out DistanceToMoveHigh, 0); 
     ReadFile(Handle, Buffer, SectorSize, out BytesRead, IntPtr.Zero); 

     Console.WriteLine(Marshal.GetLastWin32Error()); // It gives 6 which translates to an INVALID_FILE_HANDLE error 
     Console.ReadKey(); 
    } 
} 

回答

2

您致電CreateFile失敗。當然你不知道,因爲你省略了錯誤檢查。閱讀文檔。您調用的所有三個函數的錯誤均由返回值發出信號。你忽略的是什麼。

您致電CreateFile返回INVALID_HANDLE_VALUE。你需要爲此進行測試。當你遇到這種情況,只有這樣,請致電GetLastWin32Error。那麼可能會返回ERROR_ACCESS_DENIED

  • 通過FILE_FLAG_DELETE_ON_CLOSE是一個錯誤。刪除該標誌。
  • 我相信共享標誌必須是FILE_SHARE_READ | FILE_SHARE_WRITE
  • 文件名必須爲@"\\.\C:"並帶有尾部冒號。
  • 而且您將需要將該進程升級執行。
0

您以錯誤的方式使用GetLastWin32Error

這裏失敗的方法是CreateFile並返回INVALID_HANDLE_VALUE(表示失敗)。要確定出了什麼問題,您必須在CreateFile之後直接撥打GetLastWin32Error
當您嘗試讀取後調用它時,當您將無效句柄傳遞給ReadFile時,錯誤當然是ERROR_INVALID_HANDLE (6)

如果失敗CreateFile後直接致電GetLastWin32Error你會得到錯誤2:

該系統找不到指定的文件。

這是因爲驅動器名稱錯過了:

string Drive = @"\\.\C:"; // <- add colon : 

我與驅動器名稱試過,但後來得到了錯誤32:

該進程無法訪問該文件,因爲它正在被另一個進程使用。

我一直試圖弄清楚如何處理...