我正在尝试调用 DeviceIoControl(IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS)
API,作为 shown here ,但我需要它首先“告诉我”它需要多少内存(与我链接到的代码不同。)
所以我这样调用它:
//First determine how much data do we need?
BYTE dummyBuff[1];
DWORD bytesReturned = 0;
if(!::DeviceIoControl(hDevice, dwIoControlCode, lpInBuffer, nInBufferSize,
dummyBuff, sizeof(dummyBuff), &bytesReturned, NULL))
{
//Check last error
int nError = ::GetLastError();
if(nOSError == ERROR_INSUFFICIENT_BUFFER ||
nOSError == ERROR_MORE_DATA)
{
//Alloc memory from 'bytesReturned' ...
}
}
但它总是返回错误代码 87
,或 ERROR_INVALID_PARAMETER
而我的 bytesReturned
始终为 0。
那我做错了什么?
最佳答案
获取所有磁盘卷范围的说明记录在 VOLUME_DISK_EXTENTS structure 下:
When the number of extents returned is greater than one (1), the error code ERROR_MORE_DATA is returned. You should call DeviceIoControl again, allocating enough buffer space based on the value of NumberOfDiskExtents after the first DeviceIoControl call.
如果传递小于 sizeof(VOLUME_DISK_EXTENTS)
的输出缓冲区,该行为也记录在 IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS control code 中:
If the output buffer is less than
sizeof(VOLUME_DISK_EXTENTS)
, the call fails, GetLastError returns ERROR_INSUFFICIENT_BUFFER, and lpBytesReturned is 0 (zero).
虽然这解释了 lpBytesReturned 中的返回值,但它没有解释错误代码 87 (ERROR_INVALID_PARAMETER
)1)。
以下代码将返回所有卷的磁盘范围:
VOLUME_DISK_EXTENTS vde = { 0 };
DWORD bytesReturned = 0;
if ( !::DeviceIoControl( hDevice, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, NULL, 0,
(void*)&vde, sizeof(vde), &bytesReturned, NULL ) )
{
// Check last error
int nError = ::GetLastError();
if ( nError != ERROR_MORE_DATA )
{
// Unexpected error -> error out
throw std::runtime_error( "DeviceIoControl() failed." );
}
size_t size = offsetof( VOLUME_DISK_EXTENTS, Extents[vde.NumberOfDiskExtents] );
std::vector<BYTE> buffer( size );
if ( !::DeviceIoControl( hDevice, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, NULL, 0,
(void*)buffer.data(), size, &bytesReturned, NULL ) )
{
// Unexpected error -> error out
throw std::runtime_error( "DeviceIoControl() failed." );
}
// At this point we have a fully populated VOLUME_DISK_EXTENTS structure
const VOLUME_DISK_EXTENTS& result =
*reinterpret_cast<const VOLUME_DISK_EXTENTS*>( buffer.data() );
}
else
{
// Call succeeded; vde is populated with single disk extent.
}
附加引用:
1) 我猜测,
BYTE[1]
开始于一个内存地址,该地址没有充分对齐 的对齐要求VOLUME_DISK_EXTENTS
。
关于c++ - 如何调用 DeviceIoControl 来检索它需要的内存量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33327177/