![](/img/trans.png)
[英]Why DeviceIoControl IOCTL_DISK_GET_DRIVE_LAYOUT_EX failed?
[英]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,並且check
為ERROR_INVALID_PARAMETER
。 checkF
是ERROR_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);
即使還不太正確,也應該更接近正確。 checkF
是ERROR_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.