Почему DeviceIoControl добавляет 12 байтов информации к предоставленному пользователем входному буферу?

Я надеюсь, что это не окажется совершенно безмозглым вопросом.

Я редактирую шаблон драйвера USB-устройства Windows WDF для отправки отформатированных данных в один из каналов массового вывода устройства; данные должны быть настроены определенным образом, чтобы устройство читало внутренний регистр.

Проблема в том, что я не могу передать данные по шине в нужном формате. Я написал небольшое тестовое приложение для перечисления устройства и вызова DeviceIoControl с входным буфером, установленным в структуру, которую я настроил в соответствии со спецификацией.

У меня есть копия трассировки шины USB для рабочего случая (выполненного драйвером, к источнику которого у меня нет доступа), и я захватил трассировку шины для того, что происходит, когда я вызываю пользовательский IOCTL в своем драйвере. То, что я вижу, проходит через шину, это структура данных, которую я установил с префиксом из двенадцати байтов данных; структура данных правильная, но я хочу знать, каковы первые двенадцать байтов данных, и не дать драйверу их отправить.

Драйвер, я считаю, был написан правильно; Я поместил некоторые отладочные трассировки в драйвер, и похоже, что буфер, полученный WdfRequestRetrieveInputMemory, уже имеет 12 байтов, поэтому похоже, что это происходит до драйвера.

Если это полезная информация, IOCTL устанавливается как METHOD_BUFFERED с FILE_ANY_ACCESS.

Соответствующая часть тестового кода, которая устанавливает это, очень проста:

const ULONG         ulBufferSize = sizeof( CONTROL_READ_DATA );
unsigned char       pBuffer[sizeof(CONTROL_READ_DATA)];
DWORD               dwBytesReturned;
CONTROL_READ_DATA*  readData = (CONTROL_READ_DATA*)pBuffer;

readData->field1 = data;
readData->field2 = moreData;
// ... all fields filled in...

// Send IOCTLs into camera
if( !::DeviceIoControl( hDevice,
                        IOCTL_CUSTOM_000,
                        &readData,
                        ulBufferSize,
                        &readData,
                        ulBufferSize,
                        &dwBytesReturned,
                        NULL ) )
{
    dwError = ::GetLastError();
    // Clean up here
    return dwError;
}

Данные, которые я вижу, проходят через шину: 80FD1200 CCCCCCCC CCCCCCCC + (Мои данные).

У кого-нибудь есть идеи?


person 8bitcartridge    schedule 16.07.2012    source источник


Ответы (2)


Вау, действительно нелепая ошибка. Обратите внимание, что я передаю адрес readData в DeviceIoControl, который сам по себе уже является указателем. Не могу поверить, что я потратил столько времени на это.

Спасибо всем!

person 8bitcartridge    schedule 16.07.2012

Выравнивание данных является виновником. Посетите http://msdn.microsoft.com/en-us/library/2e70t5y1(v=vs.80).aspx, чтобы установить его равным единице.

person Joel Lucsy    schedule 16.07.2012
comment
Спасибо за ответ, Джоэл, но, к сожалению, он все еще не работает. Я пробовал #pragma pack(1) перед определением структуры CONTROL_READ_DATA и вижу ту же проблему. - person 8bitcartridge; 17.07.2012