CreateFile не может использовать последовательный (COM) порт

Функция CreateFile полезна для открытия файлов или устройств для доступа для чтения / записи, обеспечивая дескриптор.

Третий параметр, dwShareMode, указывает, могут ли файлы / устройства впоследствии быть доступны другим. Пример с файлами:

void* pFileHandle1 = ::CreateFileA("C:\\test.txt", GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
DWORD lastError = GetLastError(); // 0, ERROR_SUCCESS
void* pFileHandle2 = ::CreateFileA("C:\\test.txt", GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
lastError = GetLastError(); // 0, ERROR_SUCCESS

Все хорошо здесь: у нас есть 2 разных дескриптора, которые могут читать / записывать один файл.

Но в моем случае я хочу использовать COM-порт:

void* pComHandle1 = ::CreateFileA("\\\\.\\COM3", GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
lastError = GetLastError(); // 0, ERROR_SUCCESS
void* pComHandle2 = ::CreateFileA("\\\\.\\COM3", GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
lastError = GetLastError(); // 5, ERROR_ACCESS_DENIED Oops!

Первый дескриптор допустим и может использоваться, но второй - INVALID_HANDLE_VALUE.

Что с этим? Разве вы не можете использовать COM-порты таким образом?

1 ответ

Решение

Цитирование документации для CreateFile:

CreateFile Функция может создать дескриптор для коммуникационного ресурса, такого как последовательный порт COM1, Для коммуникационных ресурсов dwCreationDisposition параметр должен быть OPEN_EXISTING, dwShareMode параметр должен быть нулевым (эксклюзивный доступ), а hTemplateFile параметр должен быть NULL, Можно указать доступ для чтения, записи или чтения / записи, а также можно открыть дескриптор для перекрывающегося ввода-вывода.

Из документации здесь вытекает, что объекты связи не могут быть общими, как обычные файлы. Windows API оставляет за тем, кто бы ни открыл порт, решать, как / если они хотят поделиться доступом к этому ресурсу, и оставляет за ними возможность управлять последствиями этого решения.

Чтобы поделиться портом, вы можете использовать DuplicateHandle и передайте это тому, кому вы хотите предоставить доступ к порту после того, как вы его открыли. Для дальнейшего чтения, проверьте эту древнюю статью из MSDN

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

Другие вопросы по тегам