Маршаллинг и выравнивание параметров буфера DeviceIoControl
Я пишу службу Windows CE и API-библиотеку для нее, которая оборачивает вызовы DeviceIoControl, необходимые для связи с библиотекой. Могу ли я быть уверен, что сортировка буферов памяти, переданных в функцию DeviceIoControl, не повредит данные, выровненные по памяти? Например, если я вызываю DeviceIoControl следующим образом:
int32_t value = 5; // properly aligned at 4 bytes
DeviceIoControl(handle, IOCTL_CODE, &value, sizeof(value), NULL, 0, NULL, NULL);
могу ли я справиться с этим на стороне сервиса следующим образом:
BOOL APIENTRY SRV_IOControl(DWORD data, DWORD code, PBYTE inputBuffer, DWORD inputBufferLength, /*other params*/)
{
if ((code == IOCTL_CODE) && (inputBufferLength == sizeof(int32_t)))
{
// if inputBuffer is not aligned to 4 bytes, then this may produce
// unaligned memory access failure on some ARM processors
int32_t value = *(reinterpret_cast<int32_t*>(inputBuffer));
}
//...
}
В Windows CE 6.0 каждый процесс использует свое собственное адресное пространство, поэтому операционная система должна каким-то образом распределять буфер памяти, передаваемый от клиента сервису, например, с помощью псевдонимов или копирования памяти. (Потенциальная) проблема может быть преждевременно решена на стороне службы с помощью ключевого слова расширения Visual C++ UNALIGNED (__unaligned) или путем копирования буферов в выровненный пункт назначения. Но так как все это требует дополнительной работы от разработчика и процессора, хорошо избегать этого, если известно, что проблема вообще не существует.
1 ответ
DeviceIoControl
Вызов call не изменит выравнивания каких-либо данных, которые он собирает, поэтому любое выравнивание в источнике будет тем, что вы получите в драйвере. Это не значит, что вы могли бы испортить вещи, используя UNALIGNED
в вызывающем устройстве и драйвер затем сломался бы, но если вызывающий это делает, он находится на них, и ваш драйвер все равно не должен ожидать невыровненных данных.