CreateFile not able to share serial (COM) port

南楼画角 提交于 2021-02-17 06:46:21

问题


The CreateFile function is useful for opening files or devices for read/write access, providing a handle.

The third parameter, dwShareMode, specifies if the file/device can later be accessed by others. An example, with files:

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

All good here: we have 2 different handles that can read/write a single file.

But in my case, I want to use a COM port:

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!

The first handle is valid and can be used, but the second one is INVALID_HANDLE_VALUE.

What's up with that? Can't you share COM ports that way?


回答1:


Quoting the documentation for CreateFile:

The CreateFile function can create a handle to a communications resource, such as the serial port COM1. For communications resources, the dwCreationDisposition parameter must be OPEN_EXISTING, the dwShareMode parameter must be zero (exclusive access), and the hTemplateFile parameter must be NULL. Read, write, or read/write access can be specified, and the handle can be opened for overlapped I/O.

The implication from the documentation here is that communication objects cannot be shared like ordinary files. The Windows API leaves it to whoever opened the port to decide how/if they want to share access to that resource, and leaves them to manage the consequences of that decision.

To share the port, you can use DuplicateHandle and pass that to whoever you want to grant access to the port after you've opened it. For further reading, check out this ancient article from MSDN

That said, if you want to share a COM port across multiple processes, you're better off opening it in only one of them, and using some form of IPC to transfer data. Let one process handle servicing the port.



来源:https://stackoverflow.com/questions/50215937/createfile-not-able-to-share-serial-com-port

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!