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 для передачи данных. Пусть один процесс обрабатывает обслуживание порта.