greg francois
January 6th, 2003, 03:13 PM
Dear All,
I'm trying to modify the setting sfor my modem com port. Once I made the connection using TAPI, I access the settings for my com port. Getting the settings works like a charm, but when I try to set them, I get ERROR_INVALID_HANDLE from GetLastError().
Any insight would be greatly appreciated. I enclose the part of the code in question.
Thanks
Greg
----
// HANDLE m_hCommFile;
COMMTIMEOUTS commtimeouts;
DCB dcb;
COMMPROP commprop;
DWORD fdwEvtMask;
// These are here just so you can set a breakpoint
// and see what the comm settings are. Most Comm settings
// are already set through TAPI.
GetCommState(m_hCommFile, &dcb);
GetCommProperties(m_hCommFile, &commprop);
GetCommMask(m_hCommFile, &fdwEvtMask);
GetCommTimeouts(m_hCommFile, &commtimeouts);
// SETTINS RETRIEVED WITHOUT ANY PROBLEMS
// The CommTimeout numbers are updated
commtimeouts.ReadIntervalTimeout = 250;
commtimeouts.ReadTotalTimeoutMultiplier = 0;
commtimeouts.ReadTotalTimeoutConstant = 0;
commtimeouts.WriteTotalTimeoutMultiplier = 0;
commtimeouts.WriteTotalTimeoutConstant = 0;
// the updating fails and GetLastError gives ERROR_INVALID_HANDLE
BOOL bSuccess = SetCommTimeouts(m_hCommFile, &commtimeouts);
DWORD dwLastError = GetLastError();
// I get invalid handle right here
if (dwLastError == ERROR_INVALID_HANDLE)
{
OutputDebugString("ERROR_INVALID_HANDLE");
}
DanM
January 7th, 2003, 04:21 AM
Can you check the m_hCommFile after each of the follwing calls:
GetCommState(m_hCommFile, &dcb);
GetCommProperties(m_hCommFile, &commprop);
GetCommMask(m_hCommFile, &fdwEvtMask);
GetCommTimeouts(m_hCommFile, &commtimeouts);
?
Are you sure all these calls return TRUE ?
I'm suspect GetCommProperties overwrites the other data, including the m_hCommFile (this is the reason I want you to print/check the m_hCommFile value after each call).
Looking at the COMMPROP structure documentation it seems this struct has a variable size member data wcProvChar which contains a MODEMDEVCAPS structure for a provider subtype = PST_MODEM. In this case you need to pass a bigger buffer as the parameter for GetCommProperties.
Dan
greg francois
January 7th, 2003, 12:33 PM
Hi Dan,
Thanks for your reply. I followed your instructions. Getting the modem properties (GetCommProperties, GetCommMask, GetCommState)succeed without modifying the COM port handle. However, setting the properties back (i.e., SetCommState, SetCommTimeOuts) fail, and give an invalid handle error.
I enclose my code. The main function is PrintModemInfo which takes one parameter, the index of the modem I'm using (i.e., PrintModemInfo(0) ).
Any input as to what seems wrong, would be greatly appreciated.
I tried the code at http://msdn.microsoft.com/library/default.asp?url=/library/en-us/devio/base/configuring_a_communications_resource.asp by passing my COM port handle. I got the same problem.
I don't know if it helps, my PC's internal modem is a Lucent Win modem.
Thank you,
Greg
--------------------------
BOOL ErrorMessage( );
void SetCommTimeOuts(HANDLE hFile, USHORT dwSize);
void PrintModemInfo(DWORD i)
{
LONG lRet;
HLINE hLine;
BYTE VarBuff[1024];
LPVARSTRING lpVarString = (LPVARSTRING) VarBuff;
LPTSTR pszOut = (LPTSTR) VarBuff; // Re-using the buffer
HANDLE hFile;
BYTE Buff[sizeof(COMMPROP) + sizeof(MODEMSETTINGS) + sizeof(MODEMDEVCAPS) + 4096] = {0};
USHORT dwSize = sizeof(Buff);
COMMPROP *pcp = (COMMPROP *) Buff;
PMODEMDEVCAPS pmdc = (PMODEMDEVCAPS) &pcp->wcProvChar;
lpVarString->dwTotalSize = sizeof(VarBuff);
// We have to open with OWNER on Win9x to get modem info.
// Not true on other platforms.
lRet = lineOpen(m_hLineApp, i, &hLine, 0x00010004,
0, 0, LINECALLPRIVILEGE_OWNER, LINEMEDIAMODE_DATAMODEM,
NULL);
if (lRet != 0)
{
CString str; str.Format(_T("Not a modem: lineOpen on device %lu failed"), i);
OutputDebugString( str );
return;
}
// Fill the VARSTRING structure
lRet = lineGetID( hLine, 0, 0, LINECALLSELECT_LINE, lpVarString, TEXT("comm/datamodem") );
if (lRet != 0)
{
CString str; str.Format(_T("Not a modem: lineOpen on device %lu failed"), i);
OutputDebugString( str );
return;
}
hFile = *((LPHANDLE)( (LPBYTE)lpVarString + lpVarString -> dwStringOffset) );
// Initialize the structure
pcp->wPacketLength = dwSize;
pcp->dwProvSubType = PST_MODEM;
pcp->dwProvSpec1 = COMMPROP_INITIALIZED;
BOOL bError = ErrorMessage( );
if (!GetCommProperties(hFile, pcp))
{
CString str; str.Format(_T("Not a modem: GetCommProperties on %lu failed"), i);
OutputDebugString( str );
return;
}
bError = ErrorMessage();
if (pcp->dwProvSubType != PST_MODEM)
{
CString str; str.Format(_T("Not a modem: COMMPROP.dwProvSubType != PST_MODEM on device %lu\r\n"), i);
OutputDebugString( str );
return;
}
if (pmdc->dwModemManufacturerOffset && pmdc->dwModemManufacturerSize)
{
memcpy(VarBuff, (LPVOID)(((LPBYTE) pmdc) + pmdc->dwModemManufacturerOffset), pmdc->dwModemManufacturerSize);
pszOut[pmdc->dwModemManufacturerSize] = TEXT('\0');
// On NT, this string will probably be Unicode rather than ANSI
#ifndef UNICODE
if ((VarBuff[1] == 0) && (pmdc->dwModemManufacturerSize > 1))
{
// Convert from Unicode to ANSI
CHAR szAnsi[1024];
wcstombs(szAnsi, (wchar_t *) VarBuff, 1024);
lstrcpy(pszOut, szAnsi);
}
#endif
CString str; str.Format(_T("Device %lu is a modem, Manufacturer: %s\r\n"), i, pszOut);
OutputDebugString( str );
}
else
{
CString str; str.Format(_T("Device %lu is probably a modem, MODEMDEVCAPS.dwModemManufacturer is empty\r\n"), i);
OutputDebugString( str );
}
//http://msdn.microsoft.com/library/default.asp?url=/library/en-us/devio/base/configuring_a_communications_resource.asp
SetCommTimeOuts(hFile, dwSize);
return;
}
void SetCommTimeOuts(HANDLE hFile, USHORT dwSize)
{
// Configure the comm settings.
COMMTIMEOUTS commtimeouts;
DCB dcb;
DWORD fdwEvtMask;
BOOL bError = ErrorMessage();
BOOL bSuccess = GetCommState(hFile, &dcb);
bError = ErrorMessage();
bSuccess = GetCommMask(hFile, &fdwEvtMask);
bError = ErrorMessage();
bSuccess = GetCommTimeouts(hFile, &commtimeouts);
bError = ErrorMessage();
//<---------------------------- EVERYTHING WORKS FINE UP TO THIS POINT --------------
// fAbortOnError is the only DCB dependancy in TapiComm.
// Can't guarentee that the SP will set this to what we expect.
dcb.fAbortOnError = FALSE;
bSuccess = SetCommState(hFile, &dcb); // returns 0!
bError = ErrorMessage(); // INVALID HANDLE !
bSuccess = SetCommTimeouts(hFile, &commtimeouts); // return 0!
bError = ErrorMessage(); // INVALID HANDLE !
}
BOOL ErrorMessage( )
{
DWORD dwLastError = GetLastError();
if (dwLastError == ERROR_INVALID_HANDLE)
{
OutputDebugString("ERROR_INVALID_HANDLE");
}
return (dwLastError != 0);
}
DanM
January 8th, 2003, 02:31 AM
I don't have any other ideea but I think this post may be helpfull:
http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&oe=UTF-8&selm=32d2dcfb.2605715%40msnews.microsoft.com
Dan