﻿# Разработка драйверов для 64\-битных версий Windows

В статье рассматриваются вопросы, связанные с выпуском драйверов для 64\-битных версий Windows\. Приводятся типовые проблемы и пути их решения, а также рассматриваются инструменты, упрощающие процесс разработки драйверов\.

## Введение

Выход в 2005 году первой версии операционной системы Windows для 64\-битных процессоров AMD64 поставил перед разработчиками драйверов новую задачу \- выпуск драйверов и для 32\-битных, и для 64\-битных систем\. В то время многие производители оказались не готовы к поддержке драйверов для двух систем, поэтому многие устройства так и не получили обновленных драйверов\. Тогда это было оправдано, поскольку 64\-битные системы были в новинку и не так уж много пользователей их оценило\. Однако с выходом Windows Vista x64 ситуация резко изменилась\. Теперь и домашние пользователи хотят иметь 64\-битную операционную систему, и разработчикам уже необходимо в обязательном порядке задуматься о выпуске 64\-битных версий драйверов\.

Прежде всего, возникает вопрос: Нужно ли разрабатывать 64\-битные драйверы для 64\-битных версий Windows? Ответ однозначен: "Да, нужно\!"\. Дело в том, что использовать 32\-битные драйверы на 64\-битной системе в режиме ядра невозможно\.

При разработке драйверов для 64\-битных систем нужно учесть некоторые особенности, игнорирование которых впоследствии может привести к долгим попыткам понять, почему те или иные вещи работают не так, как раньше\. MSDN достаточно полно освещает вопрос разработки 64\-битных драйверов\. Однако, иногда информация оказывается слишком разрозненной\. Поэтому в данной статье представлен обзор основных проблем и направлений для дальнейшего изучения вопроса\.

## Основные положения

При разработке драйверов для Win64 обычно желательно использовать тот же самый исходный код, что и для Win32\. Различия в коде стоит выносить в отдельные секции под условной компиляцией\.

Перечислим несколько наиболее важных положений, касающихся 64\-битных драйверов:

* Поддержка режима DMA \(Direct Memory Access\)\. Включение в драйвер поддержки 64\-битной адресации позволяет значительно повысить производительность\.
* Поддержка 32\-битного ввода\-вывода\. Если драйвер использует процедуры DMA корректно в Windows 2000, то драйвер будет нормально работать и в 64\-битных системах\.
* Драйвер должен поддерживать как 32\-битные так и 64\-битные версии команд IOCTL\.

Необходимо заметить, что Microsoft максимально возможно обеспечивает разработчиков руководствами по переносу кода в новых версиях Windows DDK\.

## Потенциальные проблемы в коде

Список потенциальных проблем при переносе кода приведен в \[[1](https://msdn.microsoft.com/en-us/library/windows/hardware/dn613903(v=vs.85).aspx), [2](https://msdn.microsoft.com/en-us/library/ff559744.aspx)\]\. Однако, там лишь названы эти проблемы, мы же подробно рассмотрим варианты их решения\.

Итак, MSDN рекомендует нам использовать:

* Новые типы данных, безопасные с точки зрения Win64\. Это, прежде всего, типы фиксированной длины, а также типы, предназначенные специально для хранения указателей\.
* Корректные строки формата в printf\-подобных функциях\. Поскольку размеры указателей на 32\-битных и 64\-битных системах разные, то использовать одну и ту же строку формата не получится\. Идеальным решением здесь является отказ от использования таких функций взамен использования их более безопасных аналогов\.
* При необходимости обрезать указатель, использовать функции PtrToLong и PtrToUlong\. Однако, лучше переписать код так, чтобы подобная операция вовсе не потребовалась\. Дело в том, что указатель после такой операции станет уже некорректным\.
* Использовать макросы FIELD\_OFFSET и TYPE\_ALIGNMENT вместо явного вычисления позиции переменной в структуре или ручного учета выравнивания\. Это связано опять же с различными типами выравнивания и размерами указателей\.

Особое внимание следует обращать на:

* Операции с участием знаковых и беззнаковых переменных\. Вопросы приведения типов переменных часто вызывают непонимание, поэтому лучше стараться их избегать\.
* Вызовы функций, где один из параметров является указателем\. Причем потенциальная ошибка может быть скрыта как внутри функции, так и вне ее, при использовании результата ее работы\.
* Использование магических констант, которые могут изменяться в зависимости от разрядности системы\. Обратите внимание, что число \-1 на 64\-битной системе уже не равно 0xffffffff, как это было на 32\-битной\. Чему оно равно? Разумеется, 0xffffffffffffffff, в то время как 0xffffffff \- это всего лишь 0x00000000ffffffff\.
* Структуры, содержащие указатели\. Так как изменения адресного пространства, произошедшие на 64\-битных системах, могут напрямую сказаться на работе драйверов\.
* Приведение указателей к каким\-либо типам данных \(int, long\)\.

## Инструменты

Для проверки работоспособности драйверов рекомендуется использовать соответствующие инструменты\. Помимо включения максимального уровня диагностики в компиляторе \(/W4 или даже /Wall\) обязательно необходимо использовать другие возможности\.

Прежде всего, посмотрите на бесплатный инструмент от Microsoft \- анализатор PREfast, если Вы еще с ним не знакомы\. Это статический анализатор кода, который обнаруживает некоторые классы ошибок, которые часто встречаются как в драйверах, так и в обычных C и C\+\+ программах\.

Статический анализатор кода общего назначения Gimpel Software PC\-lint обнаруживает, помимо некоторых из перечисленных ошибок, еще и огромное количество ошибок, встречающихся в обычных программах\.

Другой статический анализатор кода Viva64 предназначен для поиска ошибок в C\+\+ программах, проявляющихся при переносе кода с 32\-битных на 64\-битные системы\.

## Заключение

Как видите, ничего страшного в разработке 64\-битных драйверов нет и инструменты, облегчающие этот процесс, доступны\. А значит откладывать это больше не стоит\.

## Библиографический список

1. Designing for 64\-bit Windows\. [https://msdn\.microsoft\.com/en\-us/library/windows/hardware/dn613903\(v\=vs\.85\)\.aspx](https://msdn.microsoft.com/en-us/library/windows/hardware/dn613903(v=vs.85).aspx)\.
1. Porting Issues Checklist\. [https://msdn\.microsoft\.com/en\-us/library/ff559744\.aspx](https://msdn.microsoft.com/en-us/library/ff559744.aspx)\.