簡體   English   中英

C#Pinvoke無效的文件句柄

[英]C# Pinvoke invalid file handle

我對kernal32 Pinvoke函數有問題,因為它們不斷拋出INVALID_FILE_HANDLE。 該程序讀取當前硬盤的第一個扇區。 我看不到以下代碼有什么問題。

    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();
    }
}

您對CreateFile調用失敗。 當然,您不知道這一點,因為您省略了任何錯誤檢查。 閱讀文檔。 返回值表示您調用的所有三個函數的錯誤。 你忽略了。

您對CreateFile調用返回INVALID_HANDLE_VALUE 您需要對此進行測試。 當您遇到這種情況時,才調用GetLastWin32Error 然后可能會返回ERROR_ACCESS_DENIED

  • 傳遞FILE_FLAG_DELETE_ON_CLOSE是一個錯誤。 刪除該標志。
  • 我認為共享標志必須為FILE_SHARE_READ | FILE_SHARE_WRITE FILE_SHARE_READ | FILE_SHARE_WRITE
  • 文件名必須為@"\\\\.\\C:"並帶有冒號。
  • 並且您將需要提升流程的執行。

您以錯誤的方式使用GetLastWin32Error

此處失敗的方法是CreateFile ,它返回INVALID_HANDLE_VALUE (表明它失敗)。 要確定出了什么問題,必須 CreateFile 之后直接調用GetLastWin32Error
當您嘗試讀取后調用它時,錯誤當然是ERROR_INVALID_HANDLE (6)因為您向ReadFile傳遞了無效的句柄。

如果在失敗的CreateFile之后直接調用GetLastWin32Error ,則會收到錯誤2:

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

這是因為驅動器名稱缺少:

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

我嘗試使用該驅動器名稱,但出現錯誤32:

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

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM