О важности префикса «\\\\?\\\\»

В одном из своих прошлых постов я писал о получении списка доступных COM портов на основе информации в реестре. Порты там представлены в виде строк «COM1», «COM2» и т.д. В принципе ничто не мешает передавать их в таком виде в функцию CreateFile для открытия. Однако для большей надежности я советую добавлять к ним префикс «\\\\?\\\\». Зачем?

Пару лет назад я работал над одной программой, принимающей информацию по COM порту. Позволив пользователю выбрать порт, я как есть передавал его в функцию CreateFile. При работе с портами, имеющими небольшой номер все работало как надо. Но при попытке открыть порт COM22 возникала ошибка «Файл не найден». Как так?

Я просмотрел диспетчер устройств. Порт на месте. Но программа его не находила. Почему? Немного подумав, я понял, в чем дело. Оказалось, система искала его не там где надо.

Функция CreateFile может искать объекты в двух пространствах имен: файловая система, диспетчер объектов. Во избежание путаницы система запрещает создавать файлы с именами «COM1», «COM2» и т.д. Это зарезервированные имена. Встретив одно из них, функция CreateFile понимает, что речь идет не о файловой системе, а о диспетчере объектов. И ищет объект с указанным именем в его пространстве имен.

Но файлы с именем «COM22» могут существовать. Поэтому CreateFile ищет его в файловой системе и, не найдя, возвращает ошибку. В пространство имен диспетчера объектов она даже не заглядывает.

Префикс «\\\\?\\\\» говорит функции CreateFile, что указанное нами имя принадлежит пространству имен диспетчера объектов. После того как я прописал это префикс, всё заработало как надо.

«\\\\?\\\\COM22»

Как показывают мои эксперименты, система (Windows 10) не позволяет создавать файлы с именами «COM1»-«COM9», а вот файлы с именами, начиная с «COM10» вполне могут существовать.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *