This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: win32file.GetCommState incorrect handling of DCB
Type: crash Stage:
Components: Extension Modules, Windows Versions: 3rd party
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: jiaailun, loewis
Priority: normal Keywords:

Created on 2008-09-26 21:08 by jiaailun, last changed 2022-04-11 14:56 by admin. This issue is now closed.

Messages (2)
msg73888 - (view) Author: Alan Gardner (jiaailun) Date: 2008-09-26 21:08
I believe I have found a bug in win32file.GetCommState and
win32file.SetCommState.  I have seen it in Python 2.4 and Python 2.5,
running an older version of pywin32, as well as the current (212)
version.  It exists in Win2k and WinXP.  I use pyserial 2.4 as a wrapper
for the comm ports, though I believe the problem is in win32file.

The problem manifests itself when I try to open a com port in Python
after having that port open in Procomm (an old, no longer supported
terminal program).  I have only seen it happen with a particular brand
of USB to serial converters (Edgeport, made by Digi).  In these
conditions the python script will hang at the win32file.SetCommState()
command, usually timing out after 5-30 seconds, and quitting with no
error message.

After having done some probing I think I basically understand the
problem, and have a workaround, but I lack the know-how to fix it where
it should be fixed, in win32file.  When Procomm opens the port, it sets
XoffLim to 16128 and the XonLim to 15872.  When my script (actually,
serialwin32.py from pyserial) tries to open the port it first reads the
DCB with GetCommState(), changes baud rate, etc in the local PyDCB
object, and then tries to reconfigure the port with SetCommState().  

From what I can tell, SetCommState won't accept a value for XoffLim or
XonLim >4096.  For example, if I try to execute

DCB.XoffLim = 16128
SetCommState(porthandle,DCB)

I get an exception: (87, 'SetCommState', 'The parameter is incorrect.')

However, if GetCommState gets a DCB which has XoffLim = 16128, and then
that DCB is passed to SetCommState, the script hangs for several seconds
before exiting without opening the port and with no error message.  For
example, after having opened and closed the port in Procomm:

>>> DCB = GetCommState(porthandle)
>>> DCB.XoffLim
16128L
>>> SetCommState(porthandle,DCB)
(...... hangs here for several seconds ......)

If I set XoffLim and XonLim to values from 0-4096 before calling
SetCommState, then it works fine.  For example, after having opened and
closed the port in Procomm:

>>> DCB = GetCommState(porthandle)
>>> DCB.XoffLim = 128
>>> DCB.XonLim = 512
>>> SetCommState(porthandle,DCB)
>>>
This works fine, and I can go on to open the port normally.  I have
incorporated this fix into serialwin32.py which is working for me now,
but it's not an elegant solution.  I am still baffled by why
SetCommState limits Xon/XoffLim to 4096, and by what GetCommState does
to the PyDCB to make it cause SetCommState to fail so dramatically.  I
also don't understand why I only see this problem with the Edgeport USB
converters, and not with several other USB converters or hardware serial
ports.  Maybe someone with a more intimate understanding of Python and
Win32 can come up with some answers.

Thank you
-Alan Gardner
Woods Hole Oceanographic Institution
Woods Hole, MA 02543
msg73891 - (view) Author: Martin v. Löwis (loewis) * (Python committer) Date: 2008-09-26 21:34
This is the bug tracker for the Python Core project. Please report
problems with win32file to the Python-Win32 project
(http://sourceforge.net/projects/pywin32)
History
Date User Action Args
2022-04-11 14:56:39adminsetgithub: 48230
2008-09-26 21:34:04loewissetstatus: open -> closed
nosy: + loewis
messages: + msg73891
resolution: not a bug
versions: + 3rd party, - Python 2.5, Python 2.4
2008-09-26 21:08:16jiaailuncreate