簡體   English   中英

帶有IOCTL_DISK_GET_DRIVE_GEOMETRY的DeviceIoControl()失敗並返回錯誤代碼87。為什么?

[英]DeviceIoControl() with IOCTL_DISK_GET_DRIVE_GEOMETRY is failing and returning error code 87. Why?

相關代碼如下:

std::wstring path = ApplicationData::Current->LocalFolder->Path->Data();

std::wstring testFileName = path + std::wstring(L"\\TestVariablySized");
this->hMappedFile = CreateFile2(
    testFileName.c_str(),
    GENERIC_READ | GENERIC_WRITE,
    0,
    OPEN_ALWAYS,
    NULL);

uint32_t checkF = GetLastError();

DISK_GEOMETRY geo = { 0 };
DWORD bReturned = 0;

bool controlCheck = DeviceIoControl(
    (HANDLE)hMappedFile,              // handle to device
    IOCTL_DISK_GET_DRIVE_GEOMETRY, // dwIoControlCode
    NULL,                          // lpInBuffer
    0,                             // nInBufferSize
    (LPVOID)&geo,          // output buffer
    (DWORD)sizeof(geo),        // size of output buffer
    (LPDWORD)&bReturned,     // number of bytes returned
    NULL);

uint32_t check = GetLastError();

此后, controlCheck為false,並且checkERROR_INVALID_PARAMETER checkFERROR_ALREADY_EXISTS ,在這里應該不是問題。

據我所知,我以與IOCTL_DISK_GET_DRIVE_GEOMETRY文檔一致的方式調用了DeviceIoControl() ,但顯然我缺少了一些東西。 非常感謝您的幫助。

編輯:

根據收到的回復,我將內容更改如下:

HANDLE hDevice = CreateFile2(
    L"\\.\PhysicalDrive0",
    GENERIC_READ | GENERIC_WRITE,
    FILE_SHARE_READ | FILE_SHARE_WRITE,
    OPEN_EXISTING,
    NULL);

uint32_t checkF = GetLastError();

DISK_GEOMETRY geo = { 0 };
DWORD bReturned = 0;

bool controlCheck = DeviceIoControl(
    hDevice,              // handle to device
    IOCTL_DISK_GET_DRIVE_GEOMETRY, // dwIoControlCode
    NULL,                          // lpInBuffer
    0,                             // nInBufferSize
    (LPVOID)&geo,          // output buffer
    (DWORD)sizeof(geo),        // size of output buffer
    (LPDWORD)&bReturned,     // number of bytes returned
    NULL);

uint32_t check = GetLastError();

CloseHandle(hDevice);

即使還不太正確,也應該更接近正確。 checkFERROR_FILE_NOT_FOUND ,我發現很奇怪。 我也嘗試了"\\\\.\\PhysicalDrive1""\\\\.\\PhysicalDrive2" ,但收到的結果相同。 controlCheck仍然為false,但現在檢查為ERROR_INVALID_HANDLE

據我所知,我以與IOCTL_DISK_GET_DRIVE_GEOMETRY文檔一致的方式調用了DeviceIoControl()

實際上,您並非如此,因為您沒有注意本文檔的這一小竅門:

設備
要從中檢索幾何圖形的磁盤設備的句柄。 要檢索設備句柄,請調用CreateFile函數。

您不是將句柄傳遞給磁盤設備 ,而是將句柄傳遞給文件系統路徑

當調用CreateFile2()獲取磁盤設備的句柄時,您需要以\\\\.\\PhysicalDriveX格式而不是文件系統路徑指定物理設備。

另外,正如CreateFile2()文檔所述:

這樣的成功呼叫必須滿足以下要求:

  • 呼叫者必須具有管理權限。 有關更多信息,請參見以特殊特權運行。
  • dwCreationDisposition參數必須具有OPEN_EXISTING標志。
  • 打開卷或軟盤時, dwShareMode參數必須具有FILE_SHARE_WRITE標志。

您正在使用OPEN_ALWAYS而不是OPEN_EXISTING

請更仔細地閱讀CreateFile2()文檔的“物理磁盤和卷”部分。

嘗試類似這樣的方法:

std::wstring path = L"\\\\.\\PhysicalDrive0";
DWORD errCode;

hMappedFile = CreateFile2(
    path.c_str(),
    GENERIC_READ | GENERIC_WRITE,
    0,
    OPEN_EXISTING,
    NULL);

if (this->hMappedFile == INVALID_HANDLE_VALUE)
{
    errCode = GetLastError();
    // handle error as needed...
}
else
{
    DISK_GEOMETRY geo = { 0 };
    DWORD dwReturned = 0;

    bool controlCheck = DeviceIoControl(
        hMappedFile,                   // handle to device
        IOCTL_DISK_GET_DRIVE_GEOMETRY, // dwIoControlCode
        NULL,                          // lpInBuffer
        0,                             // nInBufferSize
        &geo,                          // output buffer
        sizeof(geo),                   // size of output buffer
        &dwReturned,                   // number of bytes returned
        NULL);

    if (!controlCheck)
    {
        errCode = GetLastError();
        // handle error as needed...
    }
    else
    {
        // use drive as needed...
    }

    CloseHandle(hMappedFile);
}

暫無
暫無

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

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