You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
3505 lines
111 KiB
3505 lines
111 KiB
/***************************************************************************
|
|
Name : IDENTIFY.C
|
|
Comment : Identifying modems
|
|
|
|
Copyright (c) Microsoft Corp. 1991, 1992, 1993
|
|
|
|
Revision Log
|
|
Num Date Name Description
|
|
--- -------- ---------- -----------------------------------------------
|
|
***************************************************************************/
|
|
#define USE_DEBUG_CONTEXT DEBUG_CONTEXT_T30_CLASS1
|
|
|
|
|
|
#include "prep.h"
|
|
|
|
|
|
#include "modemint.h"
|
|
//#include "fcomint.h"
|
|
#include "fdebug.h"
|
|
|
|
#include "awmodem.h"
|
|
#include "adaptive.h"
|
|
|
|
|
|
///RSL
|
|
#include "glbproto.h"
|
|
|
|
#define BIGTEMPSIZE 250
|
|
|
|
#include "inifile.h"
|
|
|
|
char szModemFaxClasses[] = "ModemFaxClasses";
|
|
char szModemSendSpeeds[] = "ModemSendSpeeds";
|
|
char szModemRecvSpeeds[] = "ModemRecvSpeeds";
|
|
char szModemId[] = "ModemId";
|
|
char szModemIdCmd[] = "ModemIdCmd";
|
|
char szClass0ModemId[] = "Class0ModemId";
|
|
char szClass2ModemId[] = "Class2ModemId";
|
|
char szClass20ModemId[] = "Class2.0ModemId";
|
|
|
|
char szResetCommand[] = "ResetCommand";
|
|
char szResetCommandGenerated[] = "ResetCommandGenerated";
|
|
char szSetupCommand[] = "SetupCommand";
|
|
char szSetupCommandGenerated[] = "SetupCommandGenerated";
|
|
char szExitCommand[] = "ExitCommand";
|
|
char szPreDialCommand[] = "PreDialCommand";
|
|
char szPreAnswerCommand[]= "PreAnswerCommand";
|
|
|
|
// RSL new UNIMODEM INF settings (FAX GENERIC)
|
|
|
|
char szHardwareFlowControl[] = "HardwareFlowControl";
|
|
char szSerialSpeedInit[] = "SerialSpeedInit";
|
|
char szSerialSpeedConnect[] = "SerialSpeedConnect";
|
|
char szAdaptiveAnswerEnable[] = "AdaptiveAnswerEnable";
|
|
|
|
// new ADAPTIVE INF file (FAX ADAPTIVE)
|
|
char szResponsesKeyName[] = "ResponsesKeyName=";
|
|
char szResponsesKeyName2[] = "ResponsesKeyName";
|
|
|
|
char szAdaptiveRecordUnique[] = "AdaptiveRecordUnique";
|
|
char szAdaptiveCodeId[] = "AdaptiveCodeId";
|
|
char szFaxClass[] = "FaxClass";
|
|
char szAnswerCommand[] = "AnswerCommand";
|
|
char szModemResponseFaxDetect[] = "ModemResponseFaxDetect";
|
|
char szModemResponseDataDetect[] = "ModemResponseDataDetect";
|
|
char szSerialSpeedFaxDetect[] = "SerialSpeedFaxDetect";
|
|
char szSerialSpeedDataDetect[] = "SerialSpeedDataDetect";
|
|
char szHostCommandFaxDetect[] = "HostCommandFaxDetect";
|
|
char szHostCommandDataDetect[] = "HostCommandDataDetect";
|
|
char szModemResponseFaxConnect[] = "ModemResponseFaxConnect";
|
|
char szModemResponseDataConnect[] = "ModemResponseDataConnect";
|
|
|
|
// how was the Modem Key created
|
|
char szModemKeyCreationId[] = "ModemKeyCreationId";
|
|
|
|
|
|
#define NUM_CL0IDCMDS 7
|
|
#define NUM_CL2IDCMDS 3
|
|
#define NUM_CL20IDCMDS 3
|
|
|
|
#define LEN_CL0IDCMDS 5
|
|
#define LEN_CL2IDCMDS 9
|
|
#define LEN_CL20IDCMDS 8
|
|
|
|
|
|
USHORT iModemFigureOutCmdsExt(PThrdGlbl pTG);
|
|
BOOL iModemCopyOEMInfo(PThrdGlbl pTG);
|
|
void SmashCapsAccordingToSettings(PThrdGlbl pTG);
|
|
|
|
|
|
NPSTR szClass0IdCmds[NUM_CL0IDCMDS] =
|
|
{
|
|
"ATI0\r",
|
|
"ATI1\r",
|
|
"ATI2\r",
|
|
"ATI3\r",
|
|
"ATI4\r",
|
|
"ATI5\r",
|
|
"ATI6\r"
|
|
};
|
|
|
|
NPSTR szClass2IdCmds[NUM_CL2IDCMDS] =
|
|
{
|
|
"AT+FMFR?\r",
|
|
"AT+FMDL?\r",
|
|
"AT+FREV?\r"
|
|
};
|
|
|
|
NPSTR szClass20IdCmds[NUM_CL20IDCMDS] =
|
|
{
|
|
"AT+FMI?\r",
|
|
"AT+FMM?\r",
|
|
"AT+FMR?\r"
|
|
};
|
|
|
|
|
|
typedef struct {
|
|
USHORT uGoClass, //@ The fax class the modem need to be put on before using the id commands.
|
|
uNum, //@ The number of strings (commands) in the command table.
|
|
uLen; //@ The maximum length (required buffer size) in the command table.
|
|
//@ (including space for a terminating NULL char).
|
|
NPSTR *CmdTable; //@ An array of strings each containing a modem id command.
|
|
NPSTR szIniEntry; //@ The name of the registry value in which the resulting
|
|
//@ is should be saved ("Class0ModemId", "Class2ModemId", "Class2.0ModemId")
|
|
|
|
} GETIDSTRUCT, near* NPGETIDSTRUCT;
|
|
|
|
GETIDSTRUCT GetIdTable[3] =
|
|
{
|
|
{ 0, NUM_CL0IDCMDS, LEN_CL0IDCMDS, szClass0IdCmds, szClass0ModemId },
|
|
{ 2, NUM_CL2IDCMDS, LEN_CL2IDCMDS, szClass2IdCmds, szClass2ModemId },
|
|
{ GOCLASS2_0, NUM_CL20IDCMDS, LEN_CL20IDCMDS, szClass20IdCmds, szClass20ModemId }
|
|
};
|
|
|
|
#define MAXCMDSIZE 128
|
|
#define MAXIDSIZE 128
|
|
#define RESPONSEBUFSIZE 256
|
|
#define SMALLTEMPSIZE 80
|
|
#define TMPSTRINGBUFSIZE (8*MAXCMDSIZE+MAXIDSIZE+RESPONSEBUFSIZE+2*SMALLTEMPSIZE+12)
|
|
// Enough space for all the lpszs below.
|
|
|
|
|
|
|
|
|
|
BOOL imodem_alloc_tmp_strings(PThrdGlbl pTG);
|
|
void imodem_free_tmp_strings(PThrdGlbl pTG);
|
|
void imodem_clear_tmp_settings(PThrdGlbl pTG);
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////
|
|
// Function:
|
|
// IsCacheIntDirty
|
|
//
|
|
// Purpose:
|
|
// This function verifies if the cached settings we have
|
|
// under HKLM\Sw\Ms\Fax\TAPIDevices is the same as the setting
|
|
// under Unimodem's key:
|
|
// HKLM\SYSTEM\CurrentControlSet\Control\Class\{4D36E96D-E325-11CE-BFC1-08002BE10318}
|
|
// If this setting is different it means that the modem driver was
|
|
// updated and we have to re-install the modem and thus update our
|
|
// cache.
|
|
// The function validates a numeric setting, which is actually stored
|
|
// as a REG_SZ in the registry and converted to UINT.
|
|
//
|
|
// Params:
|
|
// ULONG_PTR UnimodemFaxKey: An open key to Unimodem's registry,
|
|
// retrieved from a call to ProfileOpen.
|
|
// LPSTR szSetting: The setting to check, this is the same
|
|
// as appears in the docs (i.e. "FixModemClass").
|
|
// UINT uCachedValue: Our cached value, to be compared with what's
|
|
// read from Unimodem's registry.
|
|
//
|
|
// Return Value:
|
|
// TRUE - Cached value does not match Unimodem's value, need re-installation
|
|
// FALSE - Cache is not dirty, OK to continue.
|
|
//
|
|
// Author:
|
|
// Mooly Beery (MoolyB) 14-Nov-2001
|
|
///////////////////////////////////////////////////////////////////////////////////////
|
|
BOOL IsCacheIntDirty(ULONG_PTR UnimodemFaxKey, LPSTR szSetting,UINT uCachedValue)
|
|
{
|
|
BOOL fRet = FALSE;
|
|
UINT uUnimodemSetting = 0;
|
|
BOOL fExist = FALSE;
|
|
|
|
DEBUG_FUNCTION_NAME(("IsCacheIntDirty"));
|
|
|
|
if (UnimodemFaxKey)
|
|
{
|
|
uUnimodemSetting = ProfileGetInt(UnimodemFaxKey, szSetting, 0, &fExist);
|
|
if (!fExist)
|
|
{
|
|
DebugPrintEx(DEBUG_MSG, "Modem does not have a %s section in its Fax INF section",szSetting);
|
|
}
|
|
else
|
|
{
|
|
if (uUnimodemSetting!=uCachedValue)
|
|
{
|
|
fRet = TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
return fRet;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////
|
|
// Function:
|
|
// IsCacheStringDirty
|
|
//
|
|
// Purpose:
|
|
// This function verifies if the cached settings we have
|
|
// under HKLM\Sw\Ms\Fax\TAPIDevices is the same as the setting
|
|
// under Unimodem's key:
|
|
// HKLM\SYSTEM\CurrentControlSet\Control\Class\{4D36E96D-E325-11CE-BFC1-08002BE10318}
|
|
// If this setting is different it means that the modem driver was
|
|
// updated and we have to re-install the modem and thus update our
|
|
// cache.
|
|
// The function validates a string setting.
|
|
//
|
|
// Params:
|
|
// ULONG_PTR UnimodemFaxKey: An open key to Unimodem's registry,
|
|
// retrieved from a call to ProfileOpen.
|
|
// LPSTR szSetting: The setting to check, this is the same
|
|
// as appears in the docs (i.e. "FixModemClass").
|
|
// LPSTR szCachedValue: Our cached value, to be compared with what's
|
|
// read from Unimodem's registry.
|
|
//
|
|
// Return Value:
|
|
// TRUE - Cached value does not match Unimodem's value, need re-installation
|
|
// FALSE - Cache is not dirty, OK to continue.
|
|
//
|
|
// Author:
|
|
// Mooly Beery (MoolyB) 14-Nov-2001
|
|
///////////////////////////////////////////////////////////////////////////////////////
|
|
BOOL IsCacheStringDirty(ULONG_PTR UnimodemFaxKey, LPSTR szSetting,LPSTR szCachedValue)
|
|
{
|
|
BOOL fRet = FALSE;
|
|
UINT uLen = 0;
|
|
char szUnimodemSetting[MAXCMDSIZE] = {0};
|
|
|
|
DEBUG_FUNCTION_NAME(("IsCacheStringDirty"));
|
|
|
|
if (UnimodemFaxKey)
|
|
{
|
|
uLen = ProfileGetString(UnimodemFaxKey,szSetting,NULL,szUnimodemSetting,MAXCMDSIZE-1);
|
|
if (uLen==0)
|
|
{
|
|
DebugPrintEx(DEBUG_MSG, "Modem does not have a %s section in its Fax INF section",szSetting);
|
|
}
|
|
else
|
|
{
|
|
// szCachedValue has <cr> at the end, so don't include the <cr> in the compare
|
|
if (strncmp(szUnimodemSetting, szCachedValue, max(strlen(szUnimodemSetting), strlen(szCachedValue)-1)))
|
|
{
|
|
fRet = TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
return fRet;
|
|
}
|
|
|
|
|
|
BOOL
|
|
imodem_list_get_str(
|
|
PThrdGlbl pTG,
|
|
ULONG_PTR KeyList[10],
|
|
LPSTR lpszName,
|
|
LPSTR lpszCmdBuf,
|
|
UINT cbMax,
|
|
BOOL fCmd);
|
|
|
|
BOOL imodem_get_str(PThrdGlbl pTG, ULONG_PTR dwKey, LPSTR lpszName, LPSTR lpszCmdBuf, UINT cbMax,
|
|
BOOL fCmd);
|
|
|
|
BOOL SearchInfFile(PThrdGlbl pTG, LPSTR lpstrFile, LPSTR lpstr1, LPSTR lpstr2, LPSTR lpstr3, DWORD_PTR dwLocalKey);
|
|
void CheckAwmodemInf(PThrdGlbl pTG);
|
|
void ToCaps(LPBYTE lpb);
|
|
|
|
BOOL iModemGetCurrentModemInfo(PThrdGlbl pTG);
|
|
|
|
BOOL iModemSaveCurrentModemInfo(PThrdGlbl pTG);
|
|
|
|
|
|
USHORT EndWithCR( LPSTR sz, USHORT uLen)
|
|
{
|
|
if(uLen)
|
|
{
|
|
// Check if the string is terminated with a \r
|
|
if(sz[uLen-1] != '\r')
|
|
{
|
|
// add a \r
|
|
sz[uLen++] = '\r';
|
|
sz[uLen] = 0;
|
|
}
|
|
}
|
|
return uLen;
|
|
}
|
|
|
|
|
|
|
|
BOOL RemoveCR( LPSTR sz )
|
|
{
|
|
DWORD len;
|
|
|
|
if (!sz)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
len = strlen(sz);
|
|
if (len == 0)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
if (sz[len-1] == '\r')
|
|
{
|
|
sz[len-1] = 0;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
//@
|
|
//@ Sends an Id command to the modem and returns the resulting id string.
|
|
//@
|
|
USHORT GetIdResp(PThrdGlbl pTG, LPSTR szSend, USHORT uSendLen, LPBYTE lpbRespOut, USHORT cbMaxOut)
|
|
{
|
|
USHORT uRespLen;
|
|
|
|
DEBUG_FUNCTION_NAME(("GetIdResp"));
|
|
|
|
DebugPrintEx(DEBUG_MSG,"Want Id for (%s)", (LPSTR)szSend);
|
|
|
|
pTG->fMegaHertzHack = TRUE;
|
|
//@
|
|
//@ Send the id command to the modem and wait for a response followed by OK or ERROR.
|
|
//@ On return pTG->bLastReply contains the last modem response before the OK or ERROR.
|
|
//@
|
|
OfflineDialog2(pTG, (LPSTR)szSend, uSendLen, cbszOK, cbszERROR);
|
|
pTG->fMegaHertzHack=FALSE;
|
|
|
|
// sometimes we don't get the OK so try to parse what we got anyway
|
|
DebugPrintEx(DEBUG_MSG, "LastLine = (%s)",(LPSTR)(&(pTG->FComModem.bLastReply)));
|
|
uRespLen = min(cbMaxOut, _fstrlen(pTG->FComModem.bLastReply));
|
|
|
|
_fmemcpy(lpbRespOut, pTG->FComModem.bLastReply, uRespLen);
|
|
lpbRespOut[uRespLen] = 0; // zero terminate the string
|
|
|
|
return uRespLen;
|
|
}
|
|
|
|
|
|
|
|
|
|
USHORT GetIdForClass
|
|
(
|
|
PThrdGlbl pTG,
|
|
NPGETIDSTRUCT npgids,
|
|
LPBYTE lpbOut,
|
|
USHORT cbMaxOut,
|
|
LPBYTE lpbLongestId,
|
|
USHORT cbMaxLongestId,
|
|
LPBYTE lpbLongestCmd
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
The functions returns a id string for the modem.
|
|
The string is class dependent (as indicated in npgids,uGoClass).
|
|
The string will be in the format id1;id2;..idn where id<i> is the response of the
|
|
modem to command i in the input GETIDSTRUCT::CmdTable array.
|
|
It optionally returns the longest id ( form the result of the first 3 commands) and
|
|
the command that generatedthis longest id.
|
|
|
|
|
|
Arguments:
|
|
|
|
pTG [IN/OU]
|
|
A pointer to the infamous ThrdGlbl.
|
|
|
|
npgids [IN]
|
|
Pointer to GETIDSTRUCT that specifies the commands to send to get the id
|
|
|
|
lpbOut [OUT]
|
|
A buffer where the generated id string will be placed.
|
|
The string will be in the format id1;id2;..idn where id<i> is the response of the
|
|
modem to command i in the input GETIDSTRUCT::CmdTable array.
|
|
|
|
cbMaxOut [IN]
|
|
The maximum size of the above buffer
|
|
|
|
lpbLongestId [OUT] OPTIONAL
|
|
A buffer where longest id string will be placed.
|
|
Can be NULL in which case it will not be used.
|
|
|
|
cbMaxLongestId [IN] OPTIONAL
|
|
The size of the longest id buffer
|
|
|
|
lpbLongestCmd
|
|
A pointer to the command string (in the provided npgids::CmdTable) that generated
|
|
the longer id as described above.
|
|
|
|
Return Value:
|
|
|
|
|
|
--*/
|
|
{
|
|
USHORT i, j, k, uRet, uLen, uLenLong, iLong;
|
|
LPBYTE lpbLong;
|
|
|
|
DEBUG_FUNCTION_NAME(TEXT("GetIdForClass"));
|
|
|
|
cbMaxOut -= 2; // make space for trailing ; and \0
|
|
if(lpbLongestId)
|
|
cbMaxLongestId -= 1; // make space for trailing \0
|
|
uLen=0;
|
|
|
|
if(npgids->uGoClass)
|
|
{
|
|
//@
|
|
//@ Put the modem into the class required to use the id commands
|
|
//@
|
|
DebugPrintEx(DEBUG_MSG,
|
|
TEXT("Putting the modem into class %ld"),
|
|
npgids->uGoClass);
|
|
|
|
if(!iiModemGoClass(pTG, npgids->uGoClass, 0))
|
|
{
|
|
DebugPrintEx( DEBUG_ERR,
|
|
"GoClass %d failed",
|
|
npgids->uGoClass);
|
|
goto done;
|
|
}
|
|
}
|
|
|
|
for(lpbLong=NULL, uLenLong=0, i=0; i<npgids->uNum; i++)
|
|
{
|
|
//@
|
|
//@ Sent the command at index I in the command table to the modem
|
|
//@ and get the response in (*lpbOut+uLen). This effectively
|
|
//@ concatenates all the responses (seperated with ";")
|
|
//@
|
|
uRet = GetIdResp(
|
|
pTG,
|
|
npgids->CmdTable[i],
|
|
npgids->uLen,
|
|
lpbOut+uLen,
|
|
(USHORT)(cbMaxOut-uLen)
|
|
);
|
|
// find longest ID among ATI0 thru 3 only!
|
|
if(i<=3 && uLenLong < cbMaxLongestId && uRet > uLenLong)
|
|
{
|
|
//@
|
|
//@ Update the length of the longest id (but not above the
|
|
//@ max size the caller specified).
|
|
//@
|
|
uLenLong = min(uRet, cbMaxLongestId);
|
|
//@
|
|
//@ lpbLong points to the longets id
|
|
//@
|
|
lpbLong = lpbOut + uLen;
|
|
//@
|
|
//@ iLong id holds the index (0,1,2) of the longer id
|
|
//@
|
|
iLong = i;
|
|
}
|
|
uLen += uRet;
|
|
//@
|
|
//@ Seperate the ids by a ";"
|
|
//@
|
|
lpbOut[uLen++] = ';';
|
|
}
|
|
lpbOut[uLen] = 0;
|
|
|
|
if(lpbLongestId && lpbLongestCmd && cbMaxLongestId && lpbLong && uLenLong)
|
|
{
|
|
//@
|
|
//@ Copy the longest id (0,1 or 2) to the caller's buffer
|
|
//@
|
|
_fmemcpy(lpbLongestId, lpbLong, uLenLong);
|
|
lpbLongestId[uLenLong] = 0;
|
|
//@
|
|
//@ Copy the command that generated the longest id to the caller's buffer
|
|
//@
|
|
_fmemcpy(lpbLongestCmd, npgids->CmdTable[iLong], npgids->uLen);
|
|
lpbLongestCmd[npgids->uLen] = 0;
|
|
DebugPrintEx( DEBUG_MSG,
|
|
"LongestId (%s)-->(%s)",
|
|
(LPSTR)lpbLongestCmd,
|
|
(LPSTR)lpbLongestId);
|
|
}
|
|
// strip non-prinatbles. *AFTER* extracting the ModemId string!!
|
|
for(j=0, k=0; j<uLen; j++)
|
|
{
|
|
if(lpbOut[j] >= 32 && lpbOut[j] <= 127)
|
|
lpbOut[k++] = lpbOut[j];
|
|
}
|
|
uLen = k;
|
|
lpbOut[uLen] = 0;
|
|
DebugPrintEx( DEBUG_MSG,
|
|
"Class%dId (%s)",
|
|
npgids->uGoClass,
|
|
(LPSTR)lpbOut);
|
|
|
|
done:
|
|
if(npgids->uGoClass)
|
|
{
|
|
//@
|
|
//@ Go back to class 0 if we changes classes
|
|
//@
|
|
iiModemGoClass(pTG, 0, 0);
|
|
}
|
|
return uLen;
|
|
}
|
|
|
|
|
|
void iModemGetWriteIds(PThrdGlbl pTG, BOOL fGotOEMInfo)
|
|
{
|
|
// As with iModemFigureOutCmds and iModemGetCaps, we selectively
|
|
// detect ID's taking into account OEM info that's already read in...
|
|
USHORT uLen1, uLen2, uLen3;
|
|
DWORD_PTR dwKey=0;
|
|
LPSTR lpstr1 = 0, lpstr2 = 0, lpstr3 = 0;
|
|
USHORT uClasses = pTG->TmpSettings.lpMdmCaps->uClasses;
|
|
|
|
DEBUG_FUNCTION_NAME(("iModemGetWriteIds"));
|
|
|
|
uLen1 = uLen2 = uLen3 = 0;
|
|
|
|
//@ Open the device key
|
|
if (!(dwKey=ProfileOpen( pTG->FComModem.dwProfileID,
|
|
pTG->FComModem.rgchKey,
|
|
fREG_CREATE | fREG_READ | fREG_WRITE)))
|
|
|
|
{
|
|
DebugPrintEx(DEBUG_ERR,"Couldn't get location of modem info.");
|
|
goto end;
|
|
}
|
|
|
|
if (pTG->TmpSettings.dwGot & fGOTPARM_IDCMD)
|
|
{
|
|
//@
|
|
//@ We already have the id command (we read it from the registry during iModemGetCurrentModemInfo)
|
|
//@
|
|
|
|
int i=0;
|
|
|
|
if (!pTG->TmpSettings.szIDCmd[0])
|
|
{
|
|
//@
|
|
//@ We have a null ID command so we can't really do anything
|
|
//@ just save and exit.
|
|
goto SaveIDandCMD;
|
|
}
|
|
//@
|
|
//@ We have a non empty id command and can try to use it to detect the id.
|
|
//@
|
|
while(i++<2)
|
|
{
|
|
pTG->TmpSettings.szID[0]=0;
|
|
pTG->TmpSettings.szResponseBuf[0]=0;
|
|
//@ Send the id command to the modem. The id string is returned
|
|
//@ in pTG->TmpSettigns.szID
|
|
GetIdResp( pTG,
|
|
pTG->TmpSettings.szIDCmd,
|
|
(USHORT) _fstrlen(pTG->TmpSettings.szIDCmd),
|
|
pTG->TmpSettings.szID,
|
|
MAXIDSIZE);
|
|
//@
|
|
//@ Send the id command again this time putting the result
|
|
//@ in pTG->TmpSettings.szResponseBuf.
|
|
//@
|
|
GetIdResp( pTG,
|
|
pTG->TmpSettings.szIDCmd,
|
|
(USHORT)_fstrlen(pTG->TmpSettings.szIDCmd),
|
|
pTG->TmpSettings.szResponseBuf,
|
|
MAXIDSIZE);
|
|
//@
|
|
//@ Compate the two results. If they are the same then break.
|
|
//@ Otherwise try again.
|
|
//@ (Why do we need to do this comparision ????)
|
|
//@
|
|
if (!_fstrcmp(pTG->TmpSettings.szID, pTG->TmpSettings.szResponseBuf))
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
if (i>=3 || !pTG->TmpSettings.szID[0])
|
|
{
|
|
//@
|
|
//@ We failed to the the id response.
|
|
//@
|
|
|
|
DebugPrintEx( DEBUG_ERR,
|
|
"Can't get matching ID for supplied IDCMD: %s",
|
|
(LPSTR) pTG->TmpSettings.szIDCmd);
|
|
//@
|
|
//@ Nullify the command id and id held in TmpSettings.
|
|
//@
|
|
pTG->TmpSettings.szIDCmd[0]=pTG->TmpSettings.szID[0]=0;
|
|
}
|
|
else
|
|
{
|
|
//@
|
|
//@ The id command worked and we have a matching id.
|
|
//@
|
|
DebugPrintEx( DEBUG_MSG,
|
|
"OEM IDCmd=%s --> %s",
|
|
(LPSTR) pTG->TmpSettings.szIDCmd,
|
|
(LPSTR) pTG->TmpSettings.szID);
|
|
}
|
|
//@
|
|
//@ In any case we indicate that we have an id command and matchind id.
|
|
//@ (Why do we do that in the case we did not find a matching id ?)
|
|
//@ And save the results to the registry.
|
|
pTG->TmpSettings.dwGot |= (fGOTPARM_IDCMD | fGOTPARM_ID);
|
|
goto SaveIDandCMD;
|
|
|
|
}
|
|
|
|
//@
|
|
//@ This is the case where we do not have a command id that we previously found.
|
|
//@
|
|
|
|
// write ModemId first, then ModemIdCmd
|
|
|
|
// the lpszOemIDCmd and lpszOemID above).
|
|
pTG->TmpSettings.szID[0]=0;
|
|
lpstr1 = pTG->TmpSettings.szResponseBuf;
|
|
|
|
//@
|
|
//@ Get the class 0 full id string into lpstr1.
|
|
//@ Get the longest id (1st three commands) into pTG->TmpSettings.szID
|
|
//@ Get the command that generated the longest id into pTG->TmpSettings.szIDCmd
|
|
//@
|
|
uLen1 = GetIdForClass(pTG, &GetIdTable[0], lpstr1,
|
|
RESPONSEBUFSIZE, pTG->TmpSettings.szID, MAXIDSIZE,
|
|
pTG->TmpSettings.szIDCmd);
|
|
lpstr1[uLen1] = 0;
|
|
if (pTG->TmpSettings.szID[0])
|
|
{
|
|
pTG->TmpSettings.dwGot |= (fGOTPARM_IDCMD|fGOTPARM_ID);
|
|
}
|
|
|
|
//@
|
|
//@ Write the full id string for class 0 into the registry (Class0ModemId)
|
|
//@
|
|
ProfileWriteString(dwKey, GetIdTable[0].szIniEntry, lpstr1, FALSE);
|
|
|
|
|
|
|
|
if(uClasses & FAXCLASS2) //@ if the modem supports class 2
|
|
{
|
|
//@
|
|
//@ Get the class 2 full id string into lpstr2.
|
|
//@ Dont ask for longest id (not relevant for class 2).
|
|
//@ Note that lptstr2 is placed just after lpstr1 in pTG->TmpSettings.szResponseBuf
|
|
//@
|
|
lpstr2 = pTG->TmpSettings.szResponseBuf + uLen1 + 1;
|
|
uLen2 = GetIdForClass(pTG, &GetIdTable[1], lpstr2,
|
|
(USHORT)(RESPONSEBUFSIZE-uLen1-1), 0, 0, 0);
|
|
lpstr2[uLen2] = 0;
|
|
ProfileWriteString(dwKey, GetIdTable[1].szIniEntry, lpstr2, FALSE);
|
|
}
|
|
if(uClasses & FAXCLASS2_0) //@ if the modem supports class 2.0
|
|
{
|
|
lpstr3 = pTG->TmpSettings.szResponseBuf + uLen1 + uLen2 + 2;
|
|
//@
|
|
//@ Get the class 2.0 full id string into lpstr3.
|
|
//@ Dont ask for longest id (not relevant for class 2).
|
|
//@ Note that lptstr3 is placed just after lpstr2 in pTG->TmpSettings.szResponseBuf
|
|
//@
|
|
uLen3 = GetIdForClass(pTG, &GetIdTable[2], lpstr3, (USHORT)((RESPONSEBUFSIZE)-uLen1-uLen2-2), 0, 0, 0);
|
|
lpstr3[uLen3] = 0;
|
|
ProfileWriteString(dwKey, GetIdTable[2].szIniEntry, lpstr3, FALSE);
|
|
}
|
|
|
|
//@
|
|
//@ Note: At this point we changed the value of pTG->TmpSettings.szId and szIdCmd.
|
|
//@ and placed there the class 0 id and command respectively.
|
|
//@
|
|
ToCaps(lpstr1);
|
|
ToCaps(lpstr2);
|
|
ToCaps(lpstr3);
|
|
|
|
DebugPrintEx( DEBUG_MSG,
|
|
"Got Ids (%s)\r\n(%s)\r\n(%s)",
|
|
((LPSTR)(lpstr1 ? lpstr1 : "null")),
|
|
((LPSTR)(lpstr2 ? lpstr2 : "null")),
|
|
((LPSTR)(lpstr3 ? lpstr3 : "null")));
|
|
|
|
// If we've read any commands or caps from the OEM location we
|
|
// skip this...
|
|
|
|
//@
|
|
//@ This means that if we read the information from Unimodem key
|
|
//@ or find it in the adaptive answering file we will never search
|
|
//@ AWMODEM.INF or AWOEM.INF
|
|
//@
|
|
if (fGotOEMInfo || ( pTG->ModemKeyCreationId != MODEMKEY_FROM_NOTHING) )
|
|
{
|
|
DebugPrintEx(DEBUG_WRN,"Got OEM info: Skipping AWMODEM.INF file search!");
|
|
}
|
|
else
|
|
{
|
|
if (!SearchInfFile(pTG, "AWOEM.INF", lpstr1, lpstr2, lpstr3, dwKey))
|
|
{
|
|
SearchInfFile(pTG, "AWMODEM.INF", lpstr1, lpstr2, lpstr3, dwKey);
|
|
}
|
|
}
|
|
|
|
SaveIDandCMD:
|
|
|
|
ProfileWriteString(dwKey, szModemId, pTG->TmpSettings.szID, FALSE);
|
|
ProfileWriteString(dwKey, szModemIdCmd, pTG->TmpSettings.szIDCmd, TRUE);
|
|
|
|
end:
|
|
if (dwKey) ProfileClose(dwKey);
|
|
return;
|
|
}
|
|
|
|
// state: 0=ineol 1=insectionhdr 2=in midline 3=got] 4=got\r\n
|
|
// inputs: \r\n==0 space/tab=1 2=[ 3=] 4=pritables 5=others
|
|
USHORT uNext[5][6] =
|
|
{
|
|
// crlf sp [ ] asc oth
|
|
{ 0, 0, 1, 2, 2, 2 }, //in eol
|
|
{ 0, 1, 2, 3, 1, 2 }, //in sectionhdr
|
|
{ 0, 2, 2, 2, 2, 2 }, //in ordinary line
|
|
{ 4, 3, 2, 2, 2, 2 }, //found ]
|
|
{ 4, 4, 4, 4, 4, 4 } //found closing \r\n
|
|
};
|
|
|
|
#define START 0
|
|
#define INHEADER1 1
|
|
#define INHEADER2 3
|
|
#define FOUND 4
|
|
|
|
|
|
|
|
void ToCaps(LPBYTE lpb)
|
|
{
|
|
// capitalize string
|
|
USHORT i;
|
|
|
|
for(i=0; lpb && lpb[i]; i++)
|
|
{
|
|
if(lpb[i] >= 'a' && lpb[i] <= 'z')
|
|
lpb[i] -= 32;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
BOOL SearchInfFile
|
|
(
|
|
PThrdGlbl pTG,
|
|
LPSTR lpstrFile,
|
|
LPSTR lpstr1,
|
|
LPSTR lpstr2,
|
|
LPSTR lpstr3,
|
|
DWORD_PTR dwLocalKey
|
|
)
|
|
{
|
|
char bTemp[BIGTEMPSIZE];
|
|
char szHeader[SMALLTEMPSIZE+SMALLTEMPSIZE];
|
|
char bTemp2[SMALLTEMPSIZE+SMALLTEMPSIZE];
|
|
UINT uLen, state=0, input=0, uHdrLen;
|
|
HFILE hfile;
|
|
LPBYTE lpb, lpbCurr;
|
|
|
|
DEBUG_FUNCTION_NAME(("SearchInfFile"));
|
|
|
|
uLen = GetWindowsDirectory(bTemp, BIGTEMPSIZE-15);
|
|
if(!uLen)
|
|
{
|
|
return FALSE;
|
|
}
|
|
// if last char is not a \ then append a '\'
|
|
if(bTemp[uLen-1] != '\\')
|
|
{
|
|
bTemp[uLen++] = '\\';
|
|
bTemp[uLen] = 0; // add new 0 terminator
|
|
}
|
|
_fstrcpy(bTemp+uLen, lpstrFile);
|
|
if((hfile = DosOpen(bTemp, 0)) == HFILE_ERROR)
|
|
{
|
|
DebugPrintEx(DEBUG_WRN,"%s: No such file", (LPSTR)bTemp);
|
|
return FALSE;
|
|
}
|
|
|
|
uLen = 0;
|
|
lpbCurr = bTemp;
|
|
|
|
nextround:
|
|
DebugPrintEx(DEBUG_MSG,"Nextround");
|
|
state = START;
|
|
uHdrLen = 0;
|
|
for(;;)
|
|
{
|
|
if(!uLen)
|
|
{
|
|
uLen = DosRead( hfile, bTemp, sizeof(bTemp));
|
|
if(!uLen || uLen == ((UINT) -1))
|
|
goto done;
|
|
lpbCurr = bTemp;
|
|
}
|
|
|
|
switch(*lpbCurr)
|
|
{
|
|
case '\r':
|
|
case '\n': input = 0; break;
|
|
case ' ':
|
|
case '\t': input = 1; break;
|
|
case '[': input = 2; break;
|
|
case ']': input = 3; break;
|
|
default: if(*lpbCurr >= 32 && *lpbCurr < 128)
|
|
{
|
|
input = 4;
|
|
}
|
|
else
|
|
{
|
|
input = 5;
|
|
}
|
|
break;
|
|
}
|
|
state = uNext[state][input];
|
|
|
|
if(state == FOUND)
|
|
{
|
|
if(uHdrLen > 2)
|
|
{
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
goto nextround;
|
|
}
|
|
}
|
|
|
|
if(state == INHEADER1)
|
|
{
|
|
if(*lpbCurr != '[' && uHdrLen < sizeof(szHeader)-1)
|
|
szHeader[uHdrLen++] = *lpbCurr;
|
|
}
|
|
else if(state != INHEADER2)
|
|
uHdrLen=0;
|
|
|
|
lpbCurr++;
|
|
uLen--;
|
|
|
|
// szHeader[uHdrLen] = 0;
|
|
}
|
|
DebugPrintEx(DEBUG_MSG,"Found[%s]", (LPSTR)szHeader);
|
|
szHeader[uHdrLen] = 0;
|
|
|
|
// capitalize search string
|
|
ToCaps(szHeader);
|
|
|
|
DebugPrintEx(DEBUG_MSG,"Found[%s]", (LPSTR)szHeader);
|
|
|
|
if( (lpstr1 ? strstr(lpstr1, szHeader) : FALSE) ||
|
|
(lpstr2 ? strstr(lpstr2, szHeader) : FALSE) ||
|
|
(lpstr3 ? strstr(lpstr3, szHeader) : FALSE) )
|
|
{
|
|
DebugPrintEx( DEBUG_WRN,
|
|
"Copying INI file section [%s] from %s",
|
|
(LPSTR)szHeader,
|
|
(LPSTR)lpstrFile);
|
|
|
|
DosClose( hfile);
|
|
// read the whole section as profile string
|
|
if(GetPrivateProfileString(szHeader, NULL, "", bTemp, sizeof(bTemp), lpstrFile) == 0)
|
|
{
|
|
DebugPrintEx(DEBUG_ERR,"Can't read INF file section");
|
|
return FALSE;
|
|
}
|
|
// copy it to our IniFile
|
|
for(lpb=bTemp; *lpb; lpb += _fstrlen(lpb)+1)
|
|
{
|
|
// lpb is a key in the [szHeader] section of the INF file
|
|
if(GetPrivateProfileString(szHeader, lpb, "", bTemp2, sizeof(bTemp2), lpstrFile) == 0)
|
|
{
|
|
DebugPrintEx(DEBUG_ERR,"Can't read INF file entry");
|
|
}
|
|
else
|
|
{
|
|
// copy it to our IniFile
|
|
ProfileWriteString(dwLocalKey, lpb, bTemp2, FALSE);
|
|
DebugPrintEx( DEBUG_MSG,
|
|
"Wrote %s=%s",
|
|
(LPSTR)lpb,
|
|
(LPSTR)bTemp2);
|
|
}
|
|
}
|
|
// found what we wanted. Outta here
|
|
return TRUE;
|
|
}
|
|
|
|
// couldnt match, try again
|
|
DebugPrintEx(DEBUG_MSG,"No match");
|
|
goto nextround;
|
|
|
|
done:
|
|
DebugPrintEx(DEBUG_MSG,"End of INF file %s",(LPSTR)lpstrFile);
|
|
// end of inf file--close it
|
|
DosClose(hfile);
|
|
return FALSE;
|
|
}
|
|
|
|
void CheckAwmodemInf(PThrdGlbl pTG)
|
|
{
|
|
USHORT uLen;
|
|
char bTemp[BIGTEMPSIZE];
|
|
HFILE hfile;
|
|
|
|
DEBUG_FUNCTION_NAME(_T("CheckAwmodemInf"));
|
|
|
|
uLen = (USHORT)GetWindowsDirectory(bTemp, sizeof(bTemp)-15);
|
|
if(!uLen)
|
|
{
|
|
return;
|
|
}
|
|
// if last char is not a \ then append a '\'
|
|
if(bTemp[uLen-1] != '\\')
|
|
{
|
|
bTemp[uLen++] = '\\';
|
|
bTemp[uLen] = 0; // add new 0 terminator
|
|
}
|
|
_fstrcpy(bTemp+uLen, "AWMODEM.INF");
|
|
if((hfile = DosCreate(bTemp, 0)) == HFILE_ERROR)
|
|
{
|
|
DebugPrintEx(DEBUG_ERR,"Could not create %s",(LPSTR)bTemp);
|
|
}
|
|
else
|
|
{
|
|
DosWrite( hfile, (LPSTR)szAwmodemInf, sizeof(szAwmodemInf)-1);
|
|
DosClose( hfile);
|
|
DebugPrintEx(DEBUG_WRN,"Created %s",(LPSTR)bTemp);
|
|
}
|
|
return;
|
|
}
|
|
|
|
#define ADDSTRING(DST, SRC) \
|
|
u = _fstrlen(pTG->TmpSettings.SRC)+1; \
|
|
_fmemcpy(pb, pTG->TmpSettings.SRC,u); \
|
|
lpCmdTab->DST=pb;\
|
|
pb+=u;
|
|
|
|
USHORT iModemGetCmdTab
|
|
(
|
|
PThrdGlbl pTG,
|
|
LPCMDTAB lpCmdTab,
|
|
LPMODEMCAPS lpMdmCaps
|
|
)
|
|
{
|
|
USHORT uRet = INIT_INTERNAL_ERROR;
|
|
USHORT uPassCount = 0;
|
|
BOOL fDontPurge=FALSE; //If true, we won't delete section in install.
|
|
|
|
DEBUG_FUNCTION_NAME(("iModemGetCmdTab"));
|
|
|
|
if (!imodem_alloc_tmp_strings(pTG))
|
|
goto done;
|
|
|
|
pTG->TmpSettings.lpMdmCaps = lpMdmCaps;
|
|
|
|
ReadConfig:
|
|
// check for ModemIdCmd, ModemId, ModemFaxClasses,
|
|
// ResetCommand, SetupCommand, PreDialCommand, PreAnswerCommand,
|
|
// ExitCommand, FaxSerialSpeed vars
|
|
// and (if Class1) ModemSendCaps, ModemRecvCaps
|
|
// if all present [some exceptions--see below], then verify that
|
|
// ModemId is still correct (send ModemIdCmd, get ModemId)
|
|
// if correct then copy all INI values into lpMdmCaps and lpCmdTab
|
|
// else do full install
|
|
|
|
// get ModemCaps from current settings
|
|
|
|
imodem_clear_tmp_settings(pTG);
|
|
|
|
if (!iModemGetCurrentModemInfo(pTG))
|
|
{
|
|
goto DoInstall;
|
|
}
|
|
|
|
SmashCapsAccordingToSettings(pTG);
|
|
|
|
if (! pTG->fCommInitialized)
|
|
{
|
|
if( ! T30ComInit(pTG) )
|
|
{
|
|
DebugPrintEx(DEBUG_MSG,"T30ComInit failed");
|
|
goto done;
|
|
}
|
|
|
|
FComDTR(pTG, TRUE); // Raise DTR in ModemInit
|
|
FComFlush(pTG);
|
|
|
|
pTG->fCommInitialized = 1;
|
|
}
|
|
|
|
|
|
// do modem reset, or ID check won't work (because of echo)
|
|
if (!pTG->TmpSettings.szReset[0] && !pTG->TmpSettings.szResetGenerated[0])
|
|
{
|
|
DebugPrintEx(DEBUG_WRN,"NULL reset command specified!");
|
|
}
|
|
else
|
|
{
|
|
if(iModemReset(pTG, pTG->TmpSettings.szResetGenerated[0] ?
|
|
pTG->TmpSettings.szResetGenerated :
|
|
pTG->TmpSettings.szReset) < 0)
|
|
{
|
|
fDontPurge=TRUE; // we specifically don't purge in this case.
|
|
goto DoInstall;
|
|
}
|
|
}
|
|
|
|
uRet = 0;
|
|
goto done;
|
|
|
|
DoInstall:
|
|
if(uPassCount > 0)
|
|
{
|
|
DebugPrintEx(DEBUG_ERR,"Install looping!!");
|
|
uRet = INIT_INTERNAL_ERROR;
|
|
goto done;
|
|
}
|
|
uPassCount++;
|
|
|
|
// +++ currently we always do a "clean" install -- dwGot=0
|
|
// EXCEPT that we use fDontPurge do determine whether we
|
|
// delete the profile section or not.
|
|
fDontPurge=fDontPurge|| (pTG->TmpSettings.uDontPurge!=0);
|
|
imodem_clear_tmp_settings(pTG);
|
|
|
|
if(uRet = iModemInstall(pTG, fDontPurge))
|
|
{
|
|
goto done; // failed
|
|
}
|
|
else
|
|
{
|
|
goto ReadConfig; // success
|
|
}
|
|
|
|
// on success we want to go back and start over because (a) we want to check
|
|
// that everything is indeed OK and (b) UI etc may have modfied some of the
|
|
// settings so we need to go back and read them in again.
|
|
|
|
done:
|
|
if (!uRet)
|
|
{
|
|
char *pb = pTG->bModemCmds;
|
|
UINT u;
|
|
|
|
// Initialize all command strings in lpCmdTab to static buffer,
|
|
// copying from the corresponding strings in the TmpSettings structure.
|
|
// the latter strings point into
|
|
// the temporarily allocated buffer allocated in
|
|
// imodem_alloc_tmp_strings and will be freed on exit.
|
|
|
|
_fmemset(lpCmdTab, 0, sizeof(CMDTAB));
|
|
|
|
if (pTG->TmpSettings.szResetGenerated[0])
|
|
{
|
|
ADDSTRING(szReset, szResetGenerated);
|
|
}
|
|
else
|
|
{
|
|
ADDSTRING(szReset, szReset);
|
|
}
|
|
|
|
if (pTG->TmpSettings.szSetupGenerated[0])
|
|
{
|
|
ADDSTRING(szSetup, szSetupGenerated);
|
|
}
|
|
else
|
|
{
|
|
ADDSTRING(szSetup, szSetup);
|
|
}
|
|
|
|
ADDSTRING(szExit, szExit);
|
|
ADDSTRING(szPreDial, szPreDial);
|
|
ADDSTRING(szPreAnswer, szPreAnswer);
|
|
}
|
|
|
|
lpCmdTab->dwSerialSpeed = pTG->SerialSpeedInit;
|
|
lpCmdTab->dwFlags = pTG->TmpSettings.dwFlags;
|
|
imodem_free_tmp_strings(pTG);
|
|
return uRet;
|
|
}
|
|
|
|
USHORT iModemInstall
|
|
(
|
|
PThrdGlbl pTG,
|
|
BOOL fDontPurge
|
|
)
|
|
{
|
|
USHORT uRet = 0;
|
|
BOOL fGotOEMInfo = FALSE;
|
|
DWORD_PTR hkFr;
|
|
DWORD localModemKeyCreationId;
|
|
|
|
DEBUG_FUNCTION_NAME(("iModemInstall"));
|
|
|
|
CheckAwmodemInf(pTG); // check that AWMODEM.INf exist, otherwise create it
|
|
|
|
if (!pTG->TmpSettings.dwGot)
|
|
{
|
|
/////// clear settings in input //////
|
|
|
|
// Clear out persistant (registry) info...
|
|
if (!fDontPurge && !ProfileDeleteSection(DEF_BASEKEY,pTG->FComModem.rgchKey))
|
|
{
|
|
DebugPrintEx( DEBUG_WRN,
|
|
"ClearCurrentModemInfo:Can't delete section %s",
|
|
(LPSTR) pTG->FComModem.rgchKey);
|
|
}
|
|
|
|
|
|
{
|
|
ULONG_PTR key;
|
|
if (!(key=ProfileOpen(pTG->FComModem.dwProfileID, pTG->FComModem.rgchKey,
|
|
fREG_CREATE | fREG_READ | fREG_WRITE)))
|
|
{
|
|
DebugPrintEx(DEBUG_ERR,"Couldn't get location of modem info.");
|
|
}
|
|
else
|
|
{
|
|
ProfileWriteString(key, szResetCommandGenerated, "", TRUE);
|
|
ProfileWriteString(key, szSetupCommandGenerated, "", TRUE);
|
|
ProfileClose(key);
|
|
}
|
|
}
|
|
//@
|
|
//@ First lets see if the modem has a Unimodem FAX key.
|
|
//@ If it does then we will use the Unimodem FAX key settings
|
|
//@ and will not attempt to search ADAPTIVE.INF AWMODEM.INF or AWOEM.INF
|
|
//@ Note: This is different from thw W2K implementation. W2K provider
|
|
//@ looked first in ADAPTIVE.INF and if it found a match it DID NOT
|
|
//@ look for a Unimodem FAX key.
|
|
//@
|
|
|
|
pTG->ModemKeyCreationId = MODEMKEY_FROM_NOTHING;
|
|
|
|
hkFr = ProfileOpen( OEM_BASEKEY, pTG->lpszUnimodemFaxKey, fREG_READ);
|
|
if ( hkFr )
|
|
{
|
|
pTG->ModemKeyCreationId = MODEMKEY_FROM_UNIMODEM;
|
|
ProfileClose( hkFr);
|
|
//@
|
|
//@ This copies all the information from the unimodem FAX key to
|
|
//@ our registry.
|
|
//@
|
|
iModemCopyOEMInfo(pTG);
|
|
}
|
|
else
|
|
{
|
|
//@
|
|
//@ Check to see if this modem is defined in Adaptive.Inf
|
|
//@ Since the last parameret is FALSE we will not read in the record content
|
|
//@ if it contains an "AdaptiveCodeId" field (which indiciates we need to
|
|
//@ make sure what is the modem revision first). If it does not contain
|
|
//@ this field we will read the content into the pTG.
|
|
//@
|
|
SearchNewInfFile(pTG, pTG->ResponsesKeyName, NULL, FALSE);
|
|
|
|
if (pTG->fAdaptiveRecordFound)
|
|
{
|
|
if (! pTG->fAdaptiveRecordUnique)
|
|
{
|
|
//@
|
|
//@ The section indicates that a modem id identification is required.
|
|
//@ The next oddly named function will set pTG->fAdaptiveRecordUnique to 1
|
|
//@ if it identified the modem revision as a one for which
|
|
//@ adaptive answering is working.
|
|
//@
|
|
TalkToModem (pTG, FALSE); //@ void function
|
|
if (pTG->fAdaptiveRecordUnique)
|
|
{
|
|
//@
|
|
//@ Now we are we are sure the the adaptive record matches the modem.
|
|
//@ We search the INF again but this time allways read the record
|
|
//@ content into the pTG (last parameter is TRUE).
|
|
//@
|
|
SearchNewInfFile(pTG, pTG->ResponsesKeyName, NULL, TRUE);
|
|
}
|
|
else
|
|
{
|
|
//@
|
|
//@ The modem does not match the revision for which adaptive
|
|
//@ answering is enabled.
|
|
//@
|
|
pTG->fAdaptiveRecordFound = 0;
|
|
pTG->ModemClass = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (pTG->fAdaptiveRecordFound)
|
|
{
|
|
//@
|
|
//@ If we succeeded to find an adaptive record then we need
|
|
//@ to save the information we read from it into the pTG to the
|
|
//@ registry.
|
|
//@
|
|
pTG->ModemKeyCreationId = MODEMKEY_FROM_ADAPTIVE; //@ so we will know the information source
|
|
SaveInf2Registry(pTG);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
localModemKeyCreationId = pTG->ModemKeyCreationId;
|
|
pTG->AdaptiveAnswerEnable = 0; //@ we are going to read it back from the registry in a second
|
|
|
|
//
|
|
// At this point we have all the info from Adaptive.inf or Unimodem Reg.
|
|
// into Modem Reg.
|
|
// We have nothing in memory.
|
|
//
|
|
|
|
if (! pTG->ModemClass)
|
|
{
|
|
ReadModemClassFromRegistry(pTG);
|
|
}
|
|
|
|
if (! pTG->ModemClass)
|
|
{
|
|
TalkToModem(pTG, TRUE);
|
|
SaveModemClass2Registry(pTG);
|
|
}
|
|
|
|
|
|
//@
|
|
//@ Read the modem data back from the registry. (We have just written it
|
|
//@ to the registry in the preceeding functions and we want it back into
|
|
//@ memory).
|
|
//@ Note that this sets pTG->TmpSettings.dwGot with the fGOTCAPS_X, fGOTPARM_X, etc. flags
|
|
//@ Also note that this will turn off or on the adaptive answering flag
|
|
//@ (pTG->AdaptiveAnswerEnable) based on the extension configuration of the T30 FSP.
|
|
//@
|
|
iModemGetCurrentModemInfo(pTG);
|
|
pTG->ModemKeyCreationId = localModemKeyCreationId;
|
|
|
|
}
|
|
|
|
//
|
|
// We are ready now to initialize the hardware.
|
|
// Can be second init (first one is in TalkToModem
|
|
//
|
|
|
|
if(! T30ComInit(pTG) )
|
|
{
|
|
DebugPrintEx(DEBUG_ERR,"Cannot Init COM port");
|
|
// error already set to ERR_COMM_FAILED
|
|
uRet = INIT_PORTBUSY;
|
|
goto done;
|
|
}
|
|
|
|
FComDTR(pTG, TRUE); // Raise DTR in ModemInit
|
|
FComFlush(pTG);
|
|
|
|
pTG->fCommInitialized = 1;
|
|
|
|
// we use this to decide if we must read our OEM inf files or not....
|
|
//@ Make sure we have all what we need to operate. If we miss any of these
|
|
//@ we will attempt to find it in AWMODEM.INF and AWOEM.INF.
|
|
//@
|
|
//@ CMDS:
|
|
//@ fGOTCMD_Reset \
|
|
//@ fGOTCMD_Setup \
|
|
//@ fGOTCMD_PreAnswer \
|
|
//@ fGOTCMD_PreDial \
|
|
//@ fGOTCMD_PreExit
|
|
//@ CAPS:
|
|
//@ fGOTCAP_CLASSES
|
|
//@ fGOTCAP_SENDSPEEDS
|
|
//@ fGOTCAP_RECVSPEEDS
|
|
//@ PARAMS:
|
|
//@ fGOTPARM_PORTSPEED
|
|
//@ fGOTPARM_IDCMD
|
|
//@ fGOTPARM_ID
|
|
//@
|
|
fGotOEMInfo = (pTG->TmpSettings.dwGot & (fGOTCMDS|fGOTCAPS|fGOTPARMS));
|
|
|
|
// At this point, we have possibly an incompletely and/or
|
|
// incorrectly filled out set of commands and capabilities.
|
|
|
|
// must be first, or modem is in a totally unknown state
|
|
//@
|
|
//@ If the setup and reset command were not read or are not good
|
|
//@ iModemFigureOutCmdsExt attempts to find them and place them in
|
|
//@ pTG->TmpSettings.szReset and pTG->TmpSettings.szSetup
|
|
//@
|
|
if(uRet = iModemFigureOutCmdsExt(pTG))
|
|
goto done;
|
|
|
|
// iModemFigureOut leaves modem is a good (synced up) state
|
|
// this needs to be _after_ lpCmdTab is filled out
|
|
if(!iModemGetCaps( pTG,
|
|
pTG->TmpSettings.lpMdmCaps,
|
|
pTG->TmpSettings.dwSerialSpeed,
|
|
pTG->TmpSettings.szResetGenerated[0] ?
|
|
pTG->TmpSettings.szResetGenerated :
|
|
pTG->TmpSettings.szReset,
|
|
&pTG->TmpSettings.dwGot))
|
|
{
|
|
uRet = INIT_GETCAPS_FAIL;
|
|
goto done;
|
|
}
|
|
|
|
// we always save settings here because iModemGetWriteIds below
|
|
// will need to possibly override our settings so far...
|
|
iModemSaveCurrentModemInfo(pTG);
|
|
|
|
// must be last since it also does the AWMODEM.INF search
|
|
//@
|
|
//@ Note that iModemGetWriteIds will not do the INF search (and copy)
|
|
//@ if fGotOEMInfo is TRUE or if pTG->ModemKeyCreationId != MODEMKEY_FROM_NOTHING.
|
|
//@ This means that if we read the information from Unimodem the AWMODEM.INF and
|
|
//@ AWOEM.INF will be ignored. This is what we want !
|
|
//@
|
|
iModemGetWriteIds(pTG, fGotOEMInfo);
|
|
|
|
CleanModemInfStrings(pTG);
|
|
imodem_clear_tmp_settings(pTG);
|
|
|
|
// Now we've done all we can. We've got all the settings, written them to
|
|
// the INI file. Call back the UI function here. This will read the
|
|
// current settings from INI file, may modify them and returns OK, Cancel
|
|
// and Detect. On OK & Cancel, just exit. On Detect loop back to start
|
|
// of this function, but this time _skip_ UNIMODEM & do detection ourself
|
|
|
|
uRet = 0;
|
|
|
|
done:
|
|
|
|
return uRet;
|
|
}
|
|
|
|
|
|
/***-------------------- FLOW CONTROL ----------------------**********
|
|
|
|
Each modem seems to have it's own stupid way of setting
|
|
flow control. Here's a survey
|
|
|
|
Manuf which modem? Flow Sideeffects
|
|
----- ------------ ---- -----------
|
|
Rockwell RC2324AC &K4 &H unused. \Q unused.
|
|
US Robotics Sportster14400 &H2 &K0-3 used, &K4 unused. \cmds unused
|
|
Courier(HST,V32bis)
|
|
PracPeriph PP14400FXMT/SA &K4 &H unsued. \cmds unused.
|
|
PP2400EFXSA
|
|
Zoom 9600 V.32 VFX &K4 &H unused. \Q unused
|
|
UDSMotorola Fastalk \Q1 &H unused &K unused
|
|
HayesOptima Optima24/144 &K4 &H unused \cmds unused
|
|
MegaHertz P2144 \Q1 \Q4 &H unused &K unused
|
|
TwinCom 144/DF &K4 &H unused \Q unused
|
|
PCLogic ??? ??? ????
|
|
???? ??? \Q1 &H unused &K unused
|
|
ATI 2400 etc &K4 &H unused \cmds unused
|
|
MultiTech MultiModemMT1432MU &E5 &H unused &K unused \Q unused
|
|
MultiModemII MT932
|
|
MultiModemII MT224
|
|
Viva 14.4i/Fax and 9624i &K4 &H unused \Q unused &E unused
|
|
GVC "9600bps Fax Modem" \Q1 &H unused &K unused &E unused
|
|
SmartOne 1442F/1442FX &K4 &H unused \Q unused &E unused
|
|
DSI ScoutPlus *F2 &H &E &K \Q1 unused
|
|
|
|
|
|
We had &K4 and \Q1 commands being sent (until 7/10/93).
|
|
This is a potential problem for US Robotics, MultiTech
|
|
and DSI modems.
|
|
|
|
US Robotics defaults to ALL flow control disabled
|
|
DSI ScoutPlus defaults to CTS/RTS flow control
|
|
MultiTech defaults to CTS/RTS flow control
|
|
MultiTech is Class2-only, so we may not have trouble there
|
|
|
|
7/10/93
|
|
Added &H2 command to iModemReInit -- doesn't affect anyone else I think
|
|
later
|
|
Removed &H2 -- some modems use that as 'help' cmd & display a page
|
|
of help info that they refuse to exit except on pressing N or some such!
|
|
So we think the modem's hung!
|
|
later
|
|
Removed *F2 -- Starts a Flassh ROM download on Rockwell!!
|
|
|
|
****-------------------- FLOW CONTROL -------------------------*******/
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
According to "Data and Fax Communications" by Hummel,flow control
|
|
settings are as follows
|
|
|
|
xon both
|
|
&H2 &H3 -- US Robotics (though this fatally invokes Help on some modems)
|
|
&K4 -- Dallas, Hayes, Practical, Prometheus, Rockwell, Sierra, Telebit
|
|
Twincom, Zoom
|
|
\Q1 -- AT&T, Dallas, Microcom, Practical, Prometheus, Sierra
|
|
*F2 -- Prometheus (though it fatally invokes Flash ROM download on Rockwell)
|
|
#K4 -- Sierra-based fax modems
|
|
S68=3 -- Telebit
|
|
|
|
**************************************************************************/
|
|
|
|
|
|
#define AT "AT"
|
|
#define ampF "&F"
|
|
#define S0_0 "S0=0"
|
|
#define E0 "E0"
|
|
#define V1 "V1"
|
|
#define Q0 "Q0"
|
|
#define S7_60 "S7=60"
|
|
#define ampD2 "&D2"
|
|
#define ampD3 "&D3"
|
|
#define bsQ1 "\\Q1"
|
|
#define bsJ0 "\\J0"
|
|
#define ampK4 "&K4"
|
|
#define ampH2 "&H2"
|
|
#define ampI2 "&I2"
|
|
#define ampE5 "&E5"
|
|
#define cr "\r"
|
|
//#define ampC1 "&C1"
|
|
|
|
|
|
USHORT iModemFigureOutCmdsExt(PThrdGlbl pTG)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Tries to figure out the reset and setup command for the modem if the were
|
|
not read from the registry or what was read does not work.
|
|
If a reset command works the fGOTCMD_Reset is set in pTG->TmpSettings.dwGot and it is saved in pTG->TmpSettings.szReset.
|
|
If a setup command works the fGOTCMD_Setup is set in pTG->TmpSettings.dwGot and it is saved in pTG->TmpSettings.szReset.
|
|
if pTG->TmpSettings.dwSerialSpeed is not set (0) then we set it to pTG->SerialSpeedInit and turn on
|
|
the fGOTPARM_PORTSPEED flag.
|
|
|
|
Return Value:
|
|
0 if succeeded.
|
|
INIT_MODEMDEAD if the modem does not respond.
|
|
|
|
|
|
--*/
|
|
{
|
|
USHORT uLen1 = 0, uLen2 = 0;
|
|
BOOL fGotFlo;
|
|
|
|
// At this point, we have possibly an incompletely and/or
|
|
// incorrectly filled out set of commands and capabilities.
|
|
|
|
// Our job here is to use a combination of detection and
|
|
// pre-filled commands to come up with a working set of
|
|
// commands..
|
|
|
|
DEBUG_FUNCTION_NAME(_T("iModemFigureOutCmdsExt"));
|
|
|
|
if (pTG->TmpSettings.dwGot & fGOTCMD_Reset)
|
|
{
|
|
//@
|
|
//@ If we read a reset command from the registry we
|
|
//@ don't attempt to find it if it is NULL or empty.
|
|
if (!(pTG->TmpSettings.szReset)
|
|
|| !*(pTG->TmpSettings.szReset)
|
|
|| iModemReset(pTG, pTG->TmpSettings.szReset) >= 0)
|
|
{
|
|
//@ If we dont have a pre read reset command
|
|
//@ or the reset command is empty
|
|
//@ or we succeeded in getting a response from the specified reset command
|
|
//@ then we don't attemp to figure this out.
|
|
goto SkipReset;
|
|
}
|
|
else
|
|
{
|
|
DebugPrintEx( DEBUG_WRN,
|
|
"BOGUS supplied reset cmd: \"%s\"",
|
|
(LPSTR) pTG->TmpSettings.szReset);
|
|
}
|
|
}
|
|
|
|
//@
|
|
//@ We wither did not read a reset command from the registr or read
|
|
//@ a non empty one and it did not work.
|
|
//@
|
|
//@ We now try to figure out the right reset command by just trying
|
|
//@ the most common strings...
|
|
//@
|
|
|
|
// Quick test to see if we have a modem at all...
|
|
// +++ REMOVE!
|
|
_fstrcpy(pTG->TmpSettings.szSmallTemp1, AT E0 V1 cr);
|
|
if(iModemReset(pTG, pTG->TmpSettings.szSmallTemp1) < 0)
|
|
{
|
|
DebugPrintEx(DEBUG_ERR,"can't set ATE0V1");
|
|
goto modem_dead;
|
|
}
|
|
|
|
_fstrcpy(pTG->TmpSettings.szSmallTemp1, AT ampF S0_0 E0 V1 Q0 cr);
|
|
if(iModemReset(pTG, pTG->TmpSettings.szSmallTemp1) >= 0)
|
|
goto GotReset;
|
|
|
|
// too many variants, too slow, V1Q0 are default anyway
|
|
//_fstrcpy(pTG->TmpSettings.szSmallTemp1, AT ampF S0_0 E0 V1 cr);
|
|
//if(iModemReset(pTG->TmpSettings.szSmallTemp1) >= 0)
|
|
// goto GotReset;
|
|
|
|
_fstrcpy(pTG->TmpSettings.szSmallTemp1, AT ampF S0_0 E0 cr);
|
|
if(iModemReset(pTG, pTG->TmpSettings.szSmallTemp1) >= 0)
|
|
goto GotReset;
|
|
|
|
_fstrcpy(pTG->TmpSettings.szSmallTemp1, AT ampF E0 cr);
|
|
if(iModemReset(pTG, pTG->TmpSettings.szSmallTemp1) >= 0)
|
|
goto GotReset;
|
|
|
|
DebugPrintEx(DEBUG_ERR,"can't set AT&FE0");
|
|
|
|
// Purge comm here, because there may be stuff left in the output
|
|
// buffer that FComClose will try to complete, and if the modem
|
|
// is dead, that will take a while...
|
|
modem_dead:
|
|
FComFlush(pTG);
|
|
|
|
return INIT_MODEMDEAD;
|
|
|
|
GotReset:
|
|
//@
|
|
//@ We succeeded in figuring out a reset command. Turn on the fGOTCMD_Reset flag
|
|
//@ and save it in pTG->TmpSettings.szReset.
|
|
//@
|
|
pTG->TmpSettings.dwGot |= fGOTCMD_Reset;
|
|
_fstrcpy(pTG->TmpSettings.szResetGenerated, pTG->TmpSettings.szSmallTemp1);
|
|
|
|
SkipReset:
|
|
// now try setup cmd
|
|
if (pTG->TmpSettings.dwGot & fGOTCMD_Setup)
|
|
{
|
|
if (!(pTG->TmpSettings.szSetup)
|
|
|| !*(pTG->TmpSettings.szSetup)
|
|
|| OfflineDialog2(pTG, pTG->TmpSettings.szSetup,
|
|
(USHORT)_fstrlen(pTG->TmpSettings.szSetup), cbszOK,
|
|
cbszERROR)==1)
|
|
{
|
|
goto SkipSetup;
|
|
}
|
|
else
|
|
{
|
|
DebugPrintEx( DEBUG_WRN,
|
|
"BOGUS supplied setup cmd: \"%s\"\r\n",
|
|
(LPSTR) pTG->TmpSettings.szSetup);
|
|
}
|
|
}
|
|
_fstrcpy(pTG->TmpSettings.szSmallTemp1, AT);
|
|
uLen2 = sizeof(AT)-1;
|
|
|
|
if(OfflineDialog2(pTG, (LPSTR)(AT S7_60 cr), sizeof(AT S7_60 cr)-1, cbszOK, cbszERROR) == 1)
|
|
{
|
|
_fstrcpy(pTG->TmpSettings.szSmallTemp1+uLen2, S7_60);
|
|
uLen2 += sizeof(S7_60)-1;
|
|
}
|
|
else
|
|
{
|
|
DebugPrintEx(DEBUG_WRN,"can't set S7=255");
|
|
}
|
|
|
|
if(OfflineDialog2(pTG, (LPSTR)(AT ampD3 cr), sizeof(AT ampD3 cr)-1, cbszOK, cbszERROR) == 1)
|
|
{
|
|
_fstrcpy(pTG->TmpSettings.szSmallTemp1+uLen2, ampD3);
|
|
uLen2 += sizeof(ampD3)-1;
|
|
}
|
|
else if(OfflineDialog2(pTG, (LPSTR)(AT ampD2 cr), sizeof(AT ampD2 cr)-1, cbszOK, cbszERROR) == 1)
|
|
{
|
|
_fstrcpy(pTG->TmpSettings.szSmallTemp1+uLen2, ampD2);
|
|
uLen2 += sizeof(ampD2)-1;
|
|
}
|
|
else
|
|
{
|
|
DebugPrintEx(DEBUG_WRN,"can't set &D3 or &D2");
|
|
}
|
|
|
|
fGotFlo=FALSE;
|
|
if(OfflineDialog2(pTG, (LPSTR)(AT ampK4 cr), sizeof(AT ampK4 cr)-1, cbszOK, cbszERROR) == 1)
|
|
{
|
|
_fstrcpy(pTG->TmpSettings.szSmallTemp1+uLen2, ampK4);
|
|
uLen2 += sizeof(ampK4)-1;
|
|
fGotFlo=TRUE;
|
|
}
|
|
|
|
// JosephJ 3/10/95: We try \Q1\J0 even if &K4 passed,
|
|
// because many japanese modems return OK to &K4 but in fact
|
|
// use \J0 for xon xoff flow control
|
|
if(OfflineDialog2(pTG, (LPSTR)(AT bsQ1 cr), sizeof(AT bsQ1 cr)-1, cbszOK, cbszERROR) == 1)
|
|
{
|
|
_fstrcpy(pTG->TmpSettings.szSmallTemp1+uLen2, bsQ1);
|
|
uLen2 += sizeof(bsQ1)-1;
|
|
|
|
if(OfflineDialog2(pTG, (LPSTR)(AT bsJ0 cr), sizeof(AT bsJ0 cr)-1, cbszOK, cbszERROR) == 1)
|
|
{
|
|
_fstrcpy(pTG->TmpSettings.szSmallTemp1+uLen2, bsJ0);
|
|
uLen2 += sizeof(bsJ0)-1;
|
|
}
|
|
fGotFlo=TRUE;
|
|
}
|
|
|
|
if (!fGotFlo)
|
|
{
|
|
DebugPrintEx(DEBUG_WRN,"can't set &K4 or \\Q1, trying &K5");
|
|
if(OfflineDialog2(pTG, (LPSTR)(AT ampE5 cr), sizeof(AT ampE5 cr)-1, cbszOK, cbszERROR) == 1)
|
|
{
|
|
_fstrcpy(pTG->TmpSettings.szSmallTemp1+uLen2, ampE5);
|
|
uLen2 += sizeof(ampE5)-1;
|
|
fGotFlo=TRUE;
|
|
}
|
|
}
|
|
|
|
_fstrcpy(pTG->TmpSettings.szSmallTemp1+uLen2, cr);
|
|
uLen2 += sizeof(cr)-1;
|
|
|
|
_fstrcpy(pTG->TmpSettings.szSetupGenerated, pTG->TmpSettings.szSmallTemp1);
|
|
pTG->TmpSettings.dwGot |=fGOTCMD_Setup;
|
|
|
|
SkipSetup:
|
|
|
|
if (!pTG->TmpSettings.dwSerialSpeed)
|
|
{
|
|
pTG->TmpSettings.dwSerialSpeed = pTG->SerialSpeedInit;
|
|
pTG->TmpSettings.dwGot |=fGOTPARM_PORTSPEED;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void
|
|
TalkToModem
|
|
(
|
|
PThrdGlbl pTG,
|
|
BOOL fGetClass
|
|
)
|
|
{
|
|
|
|
char Command [400];
|
|
char Response[1000];
|
|
DWORD RespLen;
|
|
USHORT uRet;
|
|
char *lpBeg;
|
|
char *lpCur;
|
|
|
|
#define uMULTILINE_SAVEENTIRE 0x1234
|
|
|
|
//
|
|
// This function implements special case modems firmware identification
|
|
// as well as modem class identification.
|
|
//
|
|
|
|
DEBUG_FUNCTION_NAME(("TalkToModem"));
|
|
|
|
if ( (! fGetClass) && (pTG->AdaptiveCodeId != 1) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Initialize modem
|
|
//
|
|
|
|
if(! T30ComInit(pTG) )
|
|
{
|
|
DebugPrintEx(DEBUG_ERR,"cannot init COM port");
|
|
return;
|
|
}
|
|
|
|
FComDTR(pTG, TRUE); // Raise DTR in ModemInit
|
|
FComFlush(pTG);
|
|
|
|
pTG->fCommInitialized = 1;
|
|
|
|
sprintf (Command, "AT E0 Q0 V1\r" );
|
|
|
|
if( (uRet = OfflineDialog2(pTG, (LPSTR) Command, (USHORT) strlen(Command), cbszOK, cbszERROR) ) != 1)
|
|
{
|
|
DebugPrintEx(DEBUG_ERR, "1 %s FAILED", Command);
|
|
return;
|
|
}
|
|
|
|
DebugPrintEx(DEBUG_MSG,"TalkToModem 1 %s rets OK", Command);
|
|
|
|
|
|
if (fGetClass)
|
|
{
|
|
//
|
|
// Get modem class
|
|
//
|
|
|
|
pTG->ModemClass=MODEM_CLASS1; // default
|
|
|
|
sprintf (Command, "AT+FCLASS=?\r" );
|
|
|
|
if( (uRet = OfflineDialog2(pTG, (LPSTR) Command, (USHORT) strlen(Command), cbszOK, cbszERROR) ) != 1)
|
|
{
|
|
DebugPrintEx(DEBUG_ERR, "TalkToModem 1 %s FAILED", Command);
|
|
return;
|
|
}
|
|
|
|
DebugPrintEx( DEBUG_MSG,
|
|
"TalkToModem 1 %s returned %s",
|
|
Command,
|
|
pTG->FComModem.bLastReply);
|
|
|
|
if (strchr(pTG->FComModem.bLastReply, '1') )
|
|
{
|
|
DebugPrintEx(DEBUG_MSG, "Default to Class1");
|
|
}
|
|
else if ( lpBeg = strchr (pTG->FComModem.bLastReply, '2') )
|
|
{
|
|
lpBeg++;
|
|
if ( *lpBeg != '.' )
|
|
{
|
|
DebugPrintEx(DEBUG_MSG, "Default to Class2");
|
|
pTG->ModemClass=MODEM_CLASS2;
|
|
}
|
|
else if ( strchr (lpBeg, '2') )
|
|
{
|
|
DebugPrintEx(DEBUG_MSG, "Default to Class2");
|
|
pTG->ModemClass=MODEM_CLASS2;
|
|
}
|
|
else
|
|
{
|
|
DebugPrintEx(DEBUG_MSG, "Default to Class2.0");
|
|
pTG->ModemClass=MODEM_CLASS2_0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DebugPrintEx(DEBUG_ERR, "Could not get valid Class answer. Default to Class1");
|
|
}
|
|
}
|
|
|
|
//
|
|
// If needed, get firmware identification.
|
|
//
|
|
|
|
switch (pTG->AdaptiveCodeId)
|
|
{
|
|
case 1:
|
|
// Sportster 28800-33600 internal/external
|
|
|
|
sprintf (Command, "ATI7\r" );
|
|
|
|
FComFlushOutput(pTG);
|
|
FComDirectAsyncWrite(pTG, (LPSTR) Command, (USHORT) strlen(Command) );
|
|
|
|
if ( ( uRet = iiModemDialog( pTG, 0, 0, 5000, uMULTILINE_SAVEENTIRE,1, TRUE,
|
|
cbszOK,
|
|
cbszERROR,
|
|
(CBPSTR)NULL) ) != 1 )
|
|
{
|
|
DebugPrintEx(DEBUG_ERR, "TalkToModem 2 %s FAILED", Command);
|
|
return;
|
|
}
|
|
|
|
DebugPrintEx(DEBUG_MSG,"TalkToModem 2 %s rets OK", Command);
|
|
|
|
RespLen = min(sizeof(Response) - 1, strlen(pTG->FComModem.bEntireReply) );
|
|
memcpy(Response, pTG->FComModem.bEntireReply, RespLen);
|
|
Response[RespLen] = 0;
|
|
|
|
ToCaps(Response);
|
|
|
|
//
|
|
// if "EPROM DATE" is "10/18/95" then the adaptive answer is broken (Hugh Riley, USR 03/25/97).
|
|
// otherwise enable adaptive answer.
|
|
// If we enabled adaptive answer and firmware is broken then the customer needs to upgrade f/w.
|
|
//
|
|
|
|
if ( ! strstr(Response, "10/18/95") )
|
|
{
|
|
pTG->fAdaptiveRecordUnique = 1;
|
|
return;
|
|
}
|
|
|
|
//
|
|
// found "10/18/95". Lets check if this is an EPROM DATE.
|
|
//
|
|
if ( ! (lpBeg = strstr(Response, "EPROM DATE") ) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
if ( ! (lpCur = strstr(lpBeg, "10/18/95") ) )
|
|
{
|
|
pTG->fAdaptiveRecordUnique = 1;
|
|
return;
|
|
}
|
|
|
|
if ( ! strstr(lpCur, "DSP DATE") )
|
|
{
|
|
pTG->fAdaptiveRecordUnique = 1;
|
|
return;
|
|
}
|
|
|
|
return;
|
|
|
|
default:
|
|
return;
|
|
|
|
}
|
|
return;
|
|
}
|
|
|
|
BOOL iModemGetCurrentModemInfo(PThrdGlbl pTG)
|
|
// Reads as much as it can from the current profile. Returns TRUE
|
|
// IFF it has read enough for a proper init.
|
|
// On failure, zero's out everything.
|
|
// All info is maintained in global TmpSettings;
|
|
{
|
|
USHORT uLen1 = 0;
|
|
USHORT uLen2 = 0;
|
|
ULONG_PTR dwKey = 0;
|
|
ULONG_PTR dwKeyAdaptiveAnswer = 0;
|
|
ULONG_PTR dwKeyAnswer = 0;
|
|
ULONG_PTR UnimodemFaxKey = 0;
|
|
BOOL fRet = FALSE;
|
|
ULONG_PTR KeyList[10] = {0};
|
|
char KeyName[200] = {0};
|
|
char lpTemp[MAXCMDSIZE] = {0};
|
|
char szClass[10] = {0};
|
|
DWORD i = 0;
|
|
UINT uTmp = 0;
|
|
|
|
LPMODEMCAPS lpMdmCaps = pTG->TmpSettings.lpMdmCaps;
|
|
|
|
DEBUG_FUNCTION_NAME(("iModemGetCurrentModemInfo"));
|
|
|
|
imodem_clear_tmp_settings(pTG);
|
|
|
|
//
|
|
// get T.30 modem Fax key
|
|
//
|
|
|
|
if ( ! (dwKey = ProfileOpen(pTG->FComModem.dwProfileID, pTG->FComModem.rgchKey, fREG_READ)))
|
|
{
|
|
goto end;
|
|
}
|
|
|
|
// open the Unimodem fax section
|
|
UnimodemFaxKey = ProfileOpen(OEM_BASEKEY,pTG->lpszUnimodemFaxKey,fREG_READ);
|
|
if (!UnimodemFaxKey)
|
|
{
|
|
// Fax section in Unimodem's registry does not exist.
|
|
// There's no need to worry if Windows Update was used
|
|
// to change settings there. Our cache is correct.
|
|
DebugPrintEx(DEBUG_MSG, "Modem does not have a Fax section in its INF");
|
|
}
|
|
|
|
//
|
|
// Lets see what modem Class we will use
|
|
//
|
|
uTmp = ProfileGetInt(dwKey, szFixModemClass, 0, FALSE);
|
|
if (IsCacheIntDirty(UnimodemFaxKey,szFixModemClass,uTmp))
|
|
{
|
|
DebugPrintEx(DEBUG_WRN, "FixModemClass cached settings are invalid, need to re-install the modem.");
|
|
fRet = FALSE;
|
|
goto end;
|
|
}
|
|
|
|
if (uTmp == 1)
|
|
{
|
|
pTG->ModemClass = MODEM_CLASS1;
|
|
}
|
|
else if (uTmp == 2)
|
|
{
|
|
pTG->ModemClass = MODEM_CLASS2;
|
|
}
|
|
else if (uTmp == 20)
|
|
{
|
|
pTG->ModemClass = MODEM_CLASS2_0;
|
|
}
|
|
|
|
if (! pTG->ModemClass)
|
|
{
|
|
DebugPrintEx(DEBUG_ERR, "MODEM CLASS was not defined.");
|
|
}
|
|
|
|
switch (pTG->ModemClass)
|
|
{
|
|
case MODEM_CLASS1 :
|
|
sprintf(szClass, "Class1");
|
|
break;
|
|
|
|
case MODEM_CLASS2 :
|
|
sprintf(szClass, "Class2");
|
|
break;
|
|
|
|
case MODEM_CLASS2_0 :
|
|
sprintf(szClass, "Class2_0");
|
|
break;
|
|
|
|
default:
|
|
sprintf(szClass, "Class1");
|
|
}
|
|
|
|
|
|
//
|
|
// depending on a requested operation, find the appropriate settings
|
|
//
|
|
|
|
if (pTG->Operation == T30_RX)
|
|
{
|
|
KeyList[0] = dwKey;
|
|
|
|
sprintf(KeyName, "%s\\%s", pTG->FComModem.rgchKey, szClass);
|
|
KeyList[1] = ProfileOpen(pTG->FComModem.dwProfileID, KeyName, fREG_READ);
|
|
|
|
sprintf(KeyName, "%s\\%s\\AdaptiveAnswer", pTG->FComModem.rgchKey, szClass);
|
|
KeyList[2] = ProfileOpen(pTG->FComModem.dwProfileID, KeyName, fREG_READ);
|
|
|
|
if (KeyList[2] == 0)
|
|
{
|
|
pTG->AdaptiveAnswerEnable = 0;
|
|
|
|
sprintf(KeyName, "%s\\%s\\Receive", pTG->FComModem.rgchKey, szClass);
|
|
KeyList[2] = ProfileOpen(pTG->FComModem.dwProfileID, KeyName, fREG_READ);
|
|
}
|
|
else
|
|
{
|
|
dwKeyAdaptiveAnswer = KeyList[2];
|
|
pTG->AdaptiveAnswerEnable = 1;
|
|
}
|
|
|
|
KeyList[3] = 0;
|
|
//
|
|
// Turn off adaptive answering if the admin disabled it via the UI
|
|
//
|
|
pTG->AdaptiveAnswerEnable = pTG->AdaptiveAnswerEnable && pTG->ExtData.bAdaptiveAnsweringEnabled;
|
|
|
|
}
|
|
else if (pTG->Operation == T30_TX)
|
|
{
|
|
KeyList[0] = dwKey;
|
|
|
|
sprintf(KeyName, "%s\\%s", pTG->FComModem.rgchKey, szClass);
|
|
KeyList[1] = ProfileOpen(pTG->FComModem.dwProfileID, KeyName, fREG_READ);
|
|
|
|
sprintf(KeyName, "%s\\%s\\Send", pTG->FComModem.rgchKey, szClass);
|
|
KeyList[2] = ProfileOpen(pTG->FComModem.dwProfileID, KeyName, fREG_READ);
|
|
|
|
KeyList[3] = 0;
|
|
}
|
|
else
|
|
{
|
|
DebugPrintEx(DEBUG_ERR, "INVALID pTG->Operation=%d",(int)pTG->Operation );
|
|
goto end;
|
|
}
|
|
|
|
if (lpMdmCaps->uClasses = (USHORT)ProfileListGetInt(KeyList, szModemFaxClasses, 0))
|
|
{
|
|
pTG->TmpSettings.dwGot |= fGOTCAP_CLASSES;
|
|
}
|
|
|
|
if(lpMdmCaps->uClasses & FAXCLASS1)
|
|
{
|
|
if (lpMdmCaps->uSendSpeeds = (USHORT)ProfileListGetInt(KeyList, szModemSendSpeeds, 0))
|
|
{
|
|
pTG->TmpSettings.dwGot |= fGOTCAP_SENDSPEEDS;
|
|
}
|
|
if (lpMdmCaps->uRecvSpeeds = (USHORT)ProfileListGetInt(KeyList, szModemRecvSpeeds, 0))
|
|
{
|
|
pTG->TmpSettings.dwGot |= fGOTCAP_RECVSPEEDS;
|
|
}
|
|
}
|
|
|
|
pTG->ModemKeyCreationId = ProfileGetInt(dwKey, szModemKeyCreationId, 0, FALSE);
|
|
|
|
//RSL 10/10/96
|
|
|
|
pTG->Inst.ProtParams.fEnableV17Send = ProfileListGetInt(KeyList, szEnableV17Send, 1);
|
|
|
|
if (IsCacheIntDirty(UnimodemFaxKey,szEnableV17Send,pTG->Inst.ProtParams.fEnableV17Send))
|
|
{
|
|
DebugPrintEx(DEBUG_WRN, "EnableV17Send cached settings are invalid, need to re-install the modem.");
|
|
fRet = FALSE;
|
|
goto end;
|
|
}
|
|
|
|
pTG->Inst.ProtParams.fEnableV17Recv = ProfileListGetInt(KeyList, szEnableV17Recv, 1);
|
|
|
|
if (IsCacheIntDirty(UnimodemFaxKey,szEnableV17Recv,pTG->Inst.ProtParams.fEnableV17Recv))
|
|
{
|
|
DebugPrintEx(DEBUG_WRN, "EnableV17Recv cached settings are invalid, need to re-install the modem.");
|
|
fRet = FALSE;
|
|
goto end;
|
|
}
|
|
|
|
uTmp = ProfileListGetInt(KeyList, szHighestSendSpeed, 0);
|
|
|
|
if (IsCacheIntDirty(UnimodemFaxKey,szHighestSendSpeed,uTmp))
|
|
{
|
|
DebugPrintEx(DEBUG_WRN, "HighestSendSpeed cached settings are invalid, need to re-install the modem.");
|
|
fRet = FALSE;
|
|
goto end;
|
|
}
|
|
|
|
if (uTmp)
|
|
{
|
|
pTG->Inst.ProtParams.HighestSendSpeed = (SHORT)uTmp;
|
|
}
|
|
|
|
uTmp = ProfileListGetInt(KeyList, szLowestSendSpeed, 0);
|
|
|
|
if (IsCacheIntDirty(UnimodemFaxKey,szLowestSendSpeed,uTmp))
|
|
{
|
|
DebugPrintEx(DEBUG_WRN, "LowestSendSpeed cached settings are invalid, need to re-install the modem.");
|
|
fRet = FALSE;
|
|
goto end;
|
|
}
|
|
|
|
if (uTmp)
|
|
{
|
|
pTG->Inst.ProtParams.LowestSendSpeed = (SHORT)uTmp;
|
|
}
|
|
|
|
uTmp = ProfileListGetInt(KeyList, szSerialSpeedInit, 0);
|
|
|
|
if (IsCacheIntDirty(UnimodemFaxKey,szSerialSpeedInit,uTmp))
|
|
{
|
|
DebugPrintEx(DEBUG_WRN, "SerialSpeedInit cached settings are invalid, need to re-install the modem.");
|
|
fRet = FALSE;
|
|
goto end;
|
|
}
|
|
|
|
if (uTmp)
|
|
{
|
|
pTG->SerialSpeedInit = (UWORD)uTmp;
|
|
pTG->SerialSpeedInitSet = 1;
|
|
pTG->TmpSettings.dwGot |= fGOTPARM_PORTSPEED;
|
|
}
|
|
|
|
uTmp = ProfileListGetInt(KeyList, szSerialSpeedConnect, 0);
|
|
if (uTmp)
|
|
{
|
|
pTG->SerialSpeedConnect = (UWORD)uTmp;
|
|
pTG->SerialSpeedConnectSet = 1;
|
|
pTG->TmpSettings.dwGot |= fGOTPARM_PORTSPEED;
|
|
}
|
|
|
|
uTmp = ProfileListGetInt(KeyList, szHardwareFlowControl, 0);
|
|
|
|
if (IsCacheIntDirty(UnimodemFaxKey,szHardwareFlowControl,uTmp))
|
|
{
|
|
DebugPrintEx(DEBUG_WRN, "HardwareFlowControl cached settings are invalid, need to re-install the modem.");
|
|
fRet = FALSE;
|
|
goto end;
|
|
}
|
|
|
|
if (uTmp)
|
|
{
|
|
pTG->fEnableHardwareFlowControl = 1;
|
|
}
|
|
|
|
|
|
DebugPrintEx( DEBUG_MSG,
|
|
"fEnableV17Send=%d, fEnableV17Recv=%d, "
|
|
"HighestSendSpeed=%d, Low=%d EnableAdaptAnswer=%d",
|
|
pTG->Inst.ProtParams.fEnableV17Send,
|
|
pTG->Inst.ProtParams.fEnableV17Recv,
|
|
pTG->Inst.ProtParams.HighestSendSpeed,
|
|
pTG->Inst.ProtParams.LowestSendSpeed,
|
|
pTG->AdaptiveAnswerEnable);
|
|
|
|
DebugPrintEx( DEBUG_MSG,
|
|
"HardwareFlowControl=%d, SerialSpeedInit=%d, SerialSpeedConnect=%d",
|
|
pTG->fEnableHardwareFlowControl,
|
|
pTG->SerialSpeedInit,
|
|
pTG->SerialSpeedConnect);
|
|
|
|
// get CmdTab. We distinguish been a command being not-specified and null.
|
|
//
|
|
|
|
if (imodem_list_get_str(pTG,KeyList,szResetCommand,pTG->TmpSettings.szReset,MAXCMDSIZE,TRUE))
|
|
{
|
|
pTG->TmpSettings.dwGot |= fGOTCMD_Reset;
|
|
}
|
|
|
|
if (IsCacheStringDirty(UnimodemFaxKey,szResetCommand,pTG->TmpSettings.szReset))
|
|
{
|
|
DebugPrintEx(DEBUG_WRN, "ResetCommand cached settings are invalid, need to re-install the modem.");
|
|
fRet = FALSE;
|
|
goto end;
|
|
}
|
|
|
|
if (imodem_list_get_str(pTG,KeyList,szSetupCommand,pTG->TmpSettings.szSetup,MAXCMDSIZE,TRUE))
|
|
{
|
|
pTG->TmpSettings.dwGot |= fGOTCMD_Setup;
|
|
}
|
|
|
|
if (IsCacheStringDirty(UnimodemFaxKey,szSetupCommand,pTG->TmpSettings.szSetup))
|
|
{
|
|
DebugPrintEx(DEBUG_WRN, "SetupCommand cached settings are invalid, need to re-install the modem.");
|
|
fRet = FALSE;
|
|
goto end;
|
|
}
|
|
|
|
if (imodem_list_get_str(pTG,KeyList,szResetCommandGenerated,pTG->TmpSettings.szResetGenerated,MAXCMDSIZE,TRUE))
|
|
{
|
|
DebugPrintEx(DEBUG_MSG, "Will use generated ResetCommand %s", pTG->TmpSettings.szResetGenerated);
|
|
}
|
|
if (imodem_list_get_str(pTG,KeyList,szSetupCommandGenerated,pTG->TmpSettings.szSetupGenerated,MAXCMDSIZE,TRUE))
|
|
{
|
|
DebugPrintEx(DEBUG_MSG, "Will use generated SetupCommand %s", pTG->TmpSettings.szSetupGenerated);
|
|
}
|
|
|
|
if (imodem_list_get_str(pTG,KeyList,szPreDialCommand,pTG->TmpSettings.szPreDial,MAXCMDSIZE,TRUE))
|
|
{
|
|
pTG->TmpSettings.dwGot |= fGOTCMD_PreDial;
|
|
}
|
|
|
|
if (IsCacheStringDirty(UnimodemFaxKey,szPreDialCommand,pTG->TmpSettings.szPreDial))
|
|
{
|
|
DebugPrintEx(DEBUG_WRN, "PreDialCommand cached settings are invalid, need to re-install the modem.");
|
|
fRet = FALSE;
|
|
goto end;
|
|
}
|
|
|
|
if (imodem_list_get_str(pTG,KeyList,szPreAnswerCommand,pTG->TmpSettings.szPreAnswer,MAXCMDSIZE,TRUE))
|
|
{
|
|
pTG->TmpSettings.dwGot |= fGOTCMD_PreAnswer;
|
|
}
|
|
|
|
if (IsCacheStringDirty(UnimodemFaxKey,szPreAnswerCommand,pTG->TmpSettings.szPreAnswer))
|
|
{
|
|
DebugPrintEx(DEBUG_WRN, "PreAnswerCommand cached settings are invalid, need to re-install the modem.");
|
|
fRet = FALSE;
|
|
goto end;
|
|
}
|
|
|
|
if (imodem_list_get_str(pTG,KeyList,szExitCommand,pTG->TmpSettings.szExit,MAXCMDSIZE,TRUE))
|
|
{
|
|
pTG->TmpSettings.dwGot |= fGOTCMD_PreExit;
|
|
}
|
|
|
|
if (IsCacheStringDirty(UnimodemFaxKey,szExitCommand,pTG->TmpSettings.szExit))
|
|
{
|
|
DebugPrintEx(DEBUG_WRN, "ExitCommand cached settings are invalid, need to re-install the modem.");
|
|
fRet = FALSE;
|
|
goto end;
|
|
}
|
|
|
|
//
|
|
// Adaptive Answer strings ONLY.
|
|
//
|
|
|
|
if (pTG->AdaptiveAnswerEnable)
|
|
{
|
|
pTG->AnswerCommandNum = 0;
|
|
|
|
// get Answer commands key
|
|
sprintf(KeyName, "%s\\Class1\\AdaptiveAnswer\\AnswerCommand", pTG->FComModem.rgchKey);
|
|
|
|
dwKeyAnswer = ProfileOpen(pTG->FComModem.dwProfileID, KeyName, fREG_READ);
|
|
|
|
if (dwKeyAnswer == 0)
|
|
{
|
|
DebugPrintEx(DEBUG_ERR, "AdaptiveAnswer\\AnswerCommand does not exist");
|
|
goto lPostAdaptiveAnswer;
|
|
}
|
|
|
|
for (i=1; i<=20; i++)
|
|
{
|
|
sprintf (KeyName, "%d", i);
|
|
if ( ! imodem_get_str(pTG, dwKeyAnswer, KeyName, lpTemp, MAXCMDSIZE, TRUE) )
|
|
{
|
|
break;
|
|
}
|
|
|
|
if (NULL != (pTG->AnswerCommand[pTG->AnswerCommandNum] = MemAlloc( strlen(lpTemp) + 1)))
|
|
{
|
|
strcpy ( pTG->AnswerCommand[pTG->AnswerCommandNum], lpTemp);
|
|
}
|
|
else
|
|
{
|
|
goto end;
|
|
}
|
|
|
|
pTG->AnswerCommandNum++;
|
|
}
|
|
|
|
ProfileClose(dwKeyAnswer);
|
|
|
|
if (pTG->AnswerCommandNum == 0)
|
|
{
|
|
DebugPrintEx(DEBUG_ERR, "AdaptiveAnswer\\AnswerCommand Zero values.");
|
|
goto lPostAdaptiveAnswer;
|
|
}
|
|
|
|
if ( imodem_get_str(pTG, dwKeyAdaptiveAnswer, szModemResponseFaxDetect, lpTemp, MAXCMDSIZE, FALSE) )
|
|
{
|
|
if (NULL != (pTG->ModemResponseFaxDetect = MemAlloc( strlen(lpTemp) + 1)))
|
|
strcpy ( pTG->ModemResponseFaxDetect, lpTemp);
|
|
else
|
|
goto end;
|
|
}
|
|
|
|
if ( imodem_get_str(pTG, dwKeyAdaptiveAnswer, szModemResponseDataDetect, lpTemp, MAXCMDSIZE, FALSE) )
|
|
{
|
|
if (NULL != (pTG->ModemResponseDataDetect = MemAlloc( strlen(lpTemp) + 1)))
|
|
strcpy ( pTG->ModemResponseDataDetect, lpTemp);
|
|
else
|
|
goto end;
|
|
}
|
|
|
|
if ( imodem_get_str(pTG, dwKeyAdaptiveAnswer, szSerialSpeedFaxDetect, lpTemp, MAXCMDSIZE, FALSE) )
|
|
{
|
|
pTG->SerialSpeedFaxDetect = (UWORD)atoi (lpTemp);
|
|
}
|
|
|
|
if ( imodem_get_str(pTG, dwKeyAdaptiveAnswer, szSerialSpeedDataDetect, lpTemp, MAXCMDSIZE, FALSE) )
|
|
{
|
|
pTG->SerialSpeedDataDetect = (UWORD)atoi (lpTemp);
|
|
}
|
|
|
|
if ( imodem_get_str(pTG, dwKeyAdaptiveAnswer, szHostCommandFaxDetect, lpTemp, MAXCMDSIZE, TRUE) )
|
|
{
|
|
if (NULL != (pTG->HostCommandFaxDetect = MemAlloc( strlen(lpTemp) + 1)))
|
|
strcpy ( pTG->HostCommandFaxDetect, lpTemp);
|
|
else
|
|
goto end;
|
|
}
|
|
|
|
if ( imodem_get_str(pTG, dwKeyAdaptiveAnswer, szHostCommandDataDetect, lpTemp, MAXCMDSIZE, TRUE) )
|
|
{
|
|
if (NULL != (pTG->HostCommandDataDetect = MemAlloc( strlen(lpTemp) + 1)))
|
|
strcpy ( pTG->HostCommandDataDetect, lpTemp);
|
|
else
|
|
goto end;
|
|
}
|
|
|
|
if ( imodem_get_str(pTG, dwKeyAdaptiveAnswer, szModemResponseFaxConnect, lpTemp, MAXCMDSIZE, FALSE) )
|
|
{
|
|
if (NULL != (pTG->ModemResponseFaxConnect = MemAlloc( strlen(lpTemp) + 1)))
|
|
strcpy ( pTG->ModemResponseFaxConnect, lpTemp);
|
|
else
|
|
goto end;
|
|
}
|
|
|
|
if ( imodem_get_str(pTG, dwKeyAdaptiveAnswer, szModemResponseDataConnect, lpTemp, MAXCMDSIZE, FALSE) )
|
|
{
|
|
if (NULL != (pTG->ModemResponseDataConnect = MemAlloc( strlen(lpTemp) + 1)))
|
|
strcpy ( pTG->ModemResponseDataConnect, lpTemp);
|
|
else
|
|
goto end;
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
lPostAdaptiveAnswer:
|
|
|
|
pTG->FixSerialSpeed = (UWORD)ProfileListGetInt(KeyList, szFixSerialSpeed, 0);
|
|
if (pTG->FixSerialSpeed)
|
|
{
|
|
pTG->TmpSettings.dwGot |= fGOTPARM_PORTSPEED;
|
|
pTG->FixSerialSpeedSet = 1;
|
|
}
|
|
|
|
if (IsCacheIntDirty(UnimodemFaxKey,szFixSerialSpeed,pTG->FixSerialSpeed))
|
|
{
|
|
DebugPrintEx(DEBUG_WRN, "FixSerialSpeed cached settings are invalid, need to re-install the modem.");
|
|
fRet = FALSE;
|
|
goto end;
|
|
}
|
|
|
|
//
|
|
// Merge 3 optional different settings for Serial Speed here
|
|
//
|
|
|
|
// FixSerialSpeed overrides the others (init/connect)
|
|
|
|
if (pTG->FixSerialSpeedSet)
|
|
{
|
|
pTG->SerialSpeedInit = pTG->FixSerialSpeed;
|
|
pTG->SerialSpeedConnect = pTG->FixSerialSpeed;
|
|
pTG->SerialSpeedInitSet = 1;
|
|
pTG->SerialSpeedConnectSet = 1;
|
|
}
|
|
|
|
// if only one of init/connect then the other is same
|
|
|
|
if ( pTG->SerialSpeedInitSet && (!pTG->SerialSpeedConnectSet) )
|
|
{
|
|
pTG->SerialSpeedConnect = pTG->SerialSpeedInit;
|
|
pTG->SerialSpeedConnectSet = 1;
|
|
}
|
|
else if ( (!pTG->SerialSpeedInitSet) && pTG->SerialSpeedConnectSet )
|
|
{
|
|
pTG->SerialSpeedInit = pTG->SerialSpeedConnect;
|
|
pTG->SerialSpeedInitSet = 1;
|
|
}
|
|
|
|
// values init/connect are always initialized.
|
|
// Use (init/connect)Set flags to determine whether there were originally set.
|
|
|
|
if (! pTG->SerialSpeedInit)
|
|
{
|
|
pTG->SerialSpeedInit = 57600;
|
|
pTG->SerialSpeedConnect = 57600;
|
|
}
|
|
|
|
// +++ Expand as necessary:
|
|
if (ProfileListGetInt(KeyList, szCL1_NO_SYNC_IF_CMD, 1))
|
|
{
|
|
pTG->TmpSettings.dwFlags |= fMDMSP_C1_NO_SYNC_IF_CMD;
|
|
}
|
|
if (ProfileListGetInt(KeyList, szANS_GOCLASS_TWICE, 1))
|
|
{
|
|
pTG->TmpSettings.dwFlags |= fMDMSP_ANS_GOCLASS_TWICE; // DEFAULT
|
|
}
|
|
#define szMDMSP_C1_FCS "Cl1FCS" // 0==dunno 1=NO 2=yes-bad
|
|
// specifies whether the modem reports the 2-byteFCS with
|
|
// received HDLC data. (Elliot bugs# 3641, 3668, 3086 report
|
|
// cases of modems sending incorrect FCS bytes).
|
|
// 9/7/95 JosephJ -- changed default from 0 to 2 because Class1 spec
|
|
// says we should NOT rely on the FCS bytes being computed correctly.
|
|
switch(ProfileListGetInt(KeyList, szMDMSP_C1_FCS, 2))
|
|
{
|
|
case 1: pTG->TmpSettings.dwFlags |= fMDMSP_C1_FCS_NO;
|
|
break;
|
|
case 2: pTG->TmpSettings.dwFlags |= fMDMSP_C1_FCS_YES_BAD;
|
|
break;
|
|
}
|
|
pTG->TmpSettings.dwGot |= fGOTFLAGS;
|
|
|
|
// Retrieve ID command.
|
|
// a way around this Id check. If IdCmd has been manually deleted, skip chk
|
|
if (imodem_list_get_str(pTG, KeyList, szModemIdCmd,
|
|
pTG->TmpSettings.szIDCmd, MAXCMDSIZE, TRUE))
|
|
{
|
|
pTG->TmpSettings.dwGot |= fGOTPARM_IDCMD;
|
|
if (imodem_list_get_str(pTG, KeyList, szModemId,
|
|
pTG->TmpSettings.szID, MAXIDSIZE, FALSE))
|
|
pTG->TmpSettings.dwGot |= fGOTPARM_ID;
|
|
}
|
|
|
|
pTG->TmpSettings.uDontPurge= (USHORT)ProfileListGetInt(KeyList, szDONT_PURGE, 0xff);
|
|
|
|
|
|
//
|
|
// Classes 2 and 2.0
|
|
//
|
|
|
|
if (pTG->ModemClass != MODEM_CLASS1)
|
|
{
|
|
uTmp = ProfileListGetInt(KeyList,szRECV_BOR, CL2_DEFAULT_SETTING);
|
|
pTG->CurrentMFRSpec.iReceiveBOR = (USHORT) uTmp;
|
|
|
|
uTmp = ProfileListGetInt(KeyList, szSEND_BOR, CL2_DEFAULT_SETTING);
|
|
pTG->CurrentMFRSpec.iSendBOR = (USHORT) uTmp;
|
|
|
|
uTmp = ProfileListGetInt(KeyList, szSW_BOR, CL2_DEFAULT_SETTING);
|
|
pTG->CurrentMFRSpec.fSWFBOR = (BOOL) uTmp;
|
|
|
|
uTmp = ProfileListGetInt(KeyList, szDC2CHAR, CL2_DEFAULT_SETTING);
|
|
pTG->CurrentMFRSpec.szDC2[0] = (CHAR) uTmp;
|
|
|
|
uTmp = ProfileListGetInt(KeyList, szIS_SIERRA, CL2_DEFAULT_SETTING);
|
|
pTG->CurrentMFRSpec.bIsSierra = (BOOL) uTmp;
|
|
|
|
uTmp = ProfileListGetInt(KeyList, szIS_EXAR, CL2_DEFAULT_SETTING);
|
|
pTG->CurrentMFRSpec.bIsExar = (BOOL) uTmp;
|
|
|
|
uTmp = ProfileListGetInt(KeyList, szSKIP_CTRL_Q, CL2_DEFAULT_SETTING);
|
|
pTG->CurrentMFRSpec.fSkipCtrlQ = (BOOL) uTmp;
|
|
}
|
|
|
|
if (dwKey)
|
|
ProfileClose(dwKey);
|
|
|
|
#define fMANDATORY (fGOTCMD_Reset|fGOTCMD_Setup|fGOTCAP_CLASSES)
|
|
#define fCLASS1MANDATORY (fMANDATORY | fGOTCAP_SENDSPEEDS | fGOTCAP_RECVSPEEDS)
|
|
fRet = (lpMdmCaps->uClasses & FAXCLASS1)
|
|
? ((pTG->TmpSettings.dwGot & fCLASS1MANDATORY) == fCLASS1MANDATORY)
|
|
: ((pTG->TmpSettings.dwGot & fMANDATORY) == fMANDATORY);
|
|
|
|
end:
|
|
|
|
for (i=1; i<10; i++)
|
|
{
|
|
if (KeyList[i] != 0)
|
|
{
|
|
ProfileClose (KeyList[i]);
|
|
}
|
|
}
|
|
|
|
if (UnimodemFaxKey)
|
|
{
|
|
ProfileClose(UnimodemFaxKey);
|
|
}
|
|
if (!fRet)
|
|
{ // Lets free all memory that was allocated here
|
|
CleanModemInfStrings (pTG);
|
|
}
|
|
|
|
return fRet;
|
|
}
|
|
|
|
|
|
void SaveCl2Settings(PThrdGlbl pTG, DWORD_PTR dwKey)
|
|
{
|
|
DEBUG_FUNCTION_NAME(("SaveCl2Settings"));
|
|
|
|
if (pTG->ModemClass != MODEM_CLASS1)
|
|
{
|
|
if (pTG->CurrentMFRSpec.iReceiveBOR != CL2_DEFAULT_SETTING)
|
|
{
|
|
wsprintf(pTG->TmpSettings.szSmallTemp1, "%lu", (unsigned long) pTG->CurrentMFRSpec.iReceiveBOR);
|
|
ProfileWriteString(dwKey, szRECV_BOR, pTG->TmpSettings.szSmallTemp1, FALSE);
|
|
}
|
|
if (pTG->CurrentMFRSpec.iSendBOR != CL2_DEFAULT_SETTING)
|
|
{
|
|
wsprintf(pTG->TmpSettings.szSmallTemp1, "%lu", (unsigned long) pTG->CurrentMFRSpec.iSendBOR);
|
|
ProfileWriteString(dwKey, szSEND_BOR, pTG->TmpSettings.szSmallTemp1, FALSE);
|
|
}
|
|
if (pTG->CurrentMFRSpec.fSWFBOR != CL2_DEFAULT_SETTING)
|
|
{
|
|
wsprintf(pTG->TmpSettings.szSmallTemp1, "%lu", (unsigned long) pTG->CurrentMFRSpec.fSWFBOR);
|
|
ProfileWriteString(dwKey, szSW_BOR, pTG->TmpSettings.szSmallTemp1, FALSE);
|
|
}
|
|
if (pTG->CurrentMFRSpec.szDC2[0] != (CHAR)CL2_DEFAULT_SETTING)
|
|
{
|
|
wsprintf(pTG->TmpSettings.szSmallTemp1, "%lu", (unsigned long) pTG->CurrentMFRSpec.szDC2[0]);
|
|
ProfileWriteString(dwKey, szDC2CHAR, pTG->TmpSettings.szSmallTemp1, FALSE);
|
|
}
|
|
if (pTG->CurrentMFRSpec.bIsSierra != CL2_DEFAULT_SETTING)
|
|
{
|
|
wsprintf(pTG->TmpSettings.szSmallTemp1, "%lu", (unsigned long) pTG->CurrentMFRSpec.bIsSierra);
|
|
ProfileWriteString(dwKey, szIS_SIERRA, pTG->TmpSettings.szSmallTemp1, FALSE);
|
|
}
|
|
if (pTG->CurrentMFRSpec.bIsExar != CL2_DEFAULT_SETTING)
|
|
{
|
|
wsprintf(pTG->TmpSettings.szSmallTemp1, "%lu", (unsigned long) pTG->CurrentMFRSpec.bIsExar);
|
|
ProfileWriteString(dwKey, szIS_EXAR, pTG->TmpSettings.szSmallTemp1, FALSE);
|
|
}
|
|
if (pTG->CurrentMFRSpec.fSkipCtrlQ != CL2_DEFAULT_SETTING)
|
|
{
|
|
wsprintf(pTG->TmpSettings.szSmallTemp1, "%lu", (unsigned long) pTG->CurrentMFRSpec.fSkipCtrlQ);
|
|
ProfileWriteString(dwKey, szSKIP_CTRL_Q, pTG->TmpSettings.szSmallTemp1, FALSE);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
BOOL iModemSaveCurrentModemInfo(PThrdGlbl pTG)
|
|
{
|
|
DWORD_PTR dwKey=0;
|
|
LPMODEMCAPS lpMdmCaps = pTG->TmpSettings.lpMdmCaps;
|
|
char KeyName[200];
|
|
DWORD_PTR dwKeyAdaptiveAnswer=0;
|
|
DWORD_PTR dwKeyAnswer=0;
|
|
DWORD i;
|
|
char szClass[10];
|
|
|
|
|
|
DEBUG_FUNCTION_NAME(("iModemSaveCurrentModemInfo"));
|
|
//
|
|
// Right now we save all major caps at the root level.
|
|
//
|
|
|
|
if (!(dwKey=ProfileOpen(pTG->FComModem.dwProfileID, pTG->FComModem.rgchKey,
|
|
fREG_CREATE | fREG_READ | fREG_WRITE)))
|
|
{
|
|
DebugPrintEx(DEBUG_ERR,"Couldn't get location of modem info.");
|
|
goto failure;
|
|
}
|
|
|
|
if (! pTG->ModemClass)
|
|
{
|
|
pTG->ModemClass = MODEM_CLASS1;
|
|
DebugPrintEx(DEBUG_ERR, "MODEM CLASS was not defined.");
|
|
}
|
|
|
|
switch (pTG->ModemClass)
|
|
{
|
|
case MODEM_CLASS1 :
|
|
ProfileWriteString(dwKey, szFixModemClass, "1", TRUE);
|
|
sprintf(szClass, "Class1");
|
|
break;
|
|
|
|
case MODEM_CLASS2 :
|
|
sprintf(szClass, "Class2");
|
|
ProfileWriteString(dwKey, szFixModemClass, "2", TRUE);
|
|
break;
|
|
|
|
case MODEM_CLASS2_0 :
|
|
sprintf(szClass, "Class2_0");
|
|
ProfileWriteString(dwKey, szFixModemClass, "20", TRUE);
|
|
break;
|
|
|
|
default:
|
|
sprintf(szClass, "Class1");
|
|
}
|
|
|
|
wsprintf(pTG->TmpSettings.szSmallTemp1, "%lu", (unsigned long) pTG->ModemKeyCreationId );
|
|
ProfileWriteString(dwKey, szModemKeyCreationId, pTG->TmpSettings.szSmallTemp1, FALSE);
|
|
|
|
////// Modem Commands
|
|
ProfileWriteString(dwKey, szResetCommand, pTG->TmpSettings.szReset, TRUE);
|
|
ProfileWriteString(dwKey, szResetCommandGenerated, pTG->TmpSettings.szResetGenerated, TRUE);
|
|
ProfileWriteString(dwKey, szSetupCommand, pTG->TmpSettings.szSetup, TRUE);
|
|
ProfileWriteString(dwKey, szSetupCommandGenerated, pTG->TmpSettings.szSetupGenerated, TRUE);
|
|
ProfileWriteString(dwKey, szExitCommand , pTG->TmpSettings.szExit, TRUE);
|
|
ProfileWriteString(dwKey, szPreDialCommand , pTG->TmpSettings.szPreDial, TRUE);
|
|
ProfileWriteString(dwKey, szPreAnswerCommand, pTG->TmpSettings.szPreAnswer, TRUE);
|
|
|
|
|
|
//
|
|
// Adaptive Answer
|
|
//
|
|
|
|
if (pTG->AdaptiveAnswerEnable)
|
|
{
|
|
// create Class key if it doesn't exist
|
|
|
|
sprintf(KeyName, "%s\\%s", pTG->FComModem.rgchKey, szClass);
|
|
|
|
dwKeyAdaptiveAnswer = ProfileOpen(pTG->FComModem.dwProfileID, KeyName, fREG_CREATE | fREG_READ | fREG_WRITE);
|
|
if (dwKeyAdaptiveAnswer == 0)
|
|
{
|
|
DebugPrintEx(DEBUG_ERR,"couldn't open Class1.");
|
|
goto failure;
|
|
}
|
|
|
|
ProfileClose(dwKeyAdaptiveAnswer);
|
|
|
|
// create Class1\AdaptiveAnswer key if it doesn't exist
|
|
|
|
sprintf(KeyName, "%s\\%s\\AdaptiveAnswer", pTG->FComModem.rgchKey, szClass);
|
|
|
|
dwKeyAdaptiveAnswer = ProfileOpen(pTG->FComModem.dwProfileID, KeyName, fREG_CREATE | fREG_READ | fREG_WRITE);
|
|
if (dwKeyAdaptiveAnswer == 0)
|
|
{
|
|
DebugPrintEx(DEBUG_ERR,"couldn't open AdaptiveAnswer.");
|
|
goto failure;
|
|
}
|
|
|
|
// create Class1\AdaptiveAnswer\Answer key if it doesn't exist
|
|
|
|
sprintf(KeyName, "%s\\%s\\AdaptiveAnswer\\AnswerCommand", pTG->FComModem.rgchKey, szClass);
|
|
|
|
dwKeyAnswer = ProfileOpen(pTG->FComModem.dwProfileID, KeyName, fREG_CREATE | fREG_READ | fREG_WRITE);
|
|
if (dwKeyAnswer == 0)
|
|
{
|
|
DebugPrintEx(DEBUG_ERR,"couldn't open AdaptiveAnswer\\AnswerCommand .");
|
|
goto failure;
|
|
}
|
|
|
|
for (i=0; i<pTG->AnswerCommandNum; i++)
|
|
{
|
|
sprintf (KeyName, "%d", i+1);
|
|
ProfileWriteString (dwKeyAnswer, KeyName , pTG->AnswerCommand[i], TRUE );
|
|
}
|
|
|
|
ProfileClose(dwKeyAnswer);
|
|
|
|
// store the rest of the AdaptiveAnswer values
|
|
|
|
if (pTG->ModemResponseFaxDetect)
|
|
ProfileWriteString (dwKeyAdaptiveAnswer, szModemResponseFaxDetect, pTG->ModemResponseFaxDetect, FALSE);
|
|
|
|
if (pTG->ModemResponseDataDetect)
|
|
ProfileWriteString (dwKeyAdaptiveAnswer, szModemResponseDataDetect, pTG->ModemResponseDataDetect, FALSE);
|
|
|
|
if (pTG->SerialSpeedFaxDetect)
|
|
{
|
|
sprintf (KeyName, "%d", pTG->SerialSpeedFaxDetect);
|
|
ProfileWriteString (dwKeyAdaptiveAnswer, szSerialSpeedFaxDetect, KeyName, FALSE);
|
|
}
|
|
|
|
if (pTG->SerialSpeedDataDetect)
|
|
{
|
|
sprintf (KeyName, "%d", pTG->SerialSpeedDataDetect);
|
|
ProfileWriteString (dwKeyAdaptiveAnswer, szSerialSpeedDataDetect, KeyName, FALSE);
|
|
}
|
|
|
|
if (pTG->HostCommandFaxDetect)
|
|
ProfileWriteString (dwKeyAdaptiveAnswer, szHostCommandFaxDetect, pTG->HostCommandFaxDetect, TRUE);
|
|
|
|
if (pTG->HostCommandDataDetect)
|
|
ProfileWriteString (dwKeyAdaptiveAnswer, szHostCommandDataDetect, pTG->HostCommandDataDetect, TRUE);
|
|
|
|
|
|
if (pTG->ModemResponseFaxConnect)
|
|
ProfileWriteString (dwKeyAdaptiveAnswer, szModemResponseFaxConnect, pTG->ModemResponseFaxConnect, FALSE);
|
|
|
|
if (pTG->ModemResponseDataConnect)
|
|
ProfileWriteString (dwKeyAdaptiveAnswer, szModemResponseDataConnect, pTG->ModemResponseDataConnect, FALSE);
|
|
|
|
|
|
ProfileClose(dwKeyAdaptiveAnswer);
|
|
|
|
}
|
|
|
|
if (pTG->fEnableHardwareFlowControl)
|
|
{
|
|
ProfileWriteString (dwKey, szHardwareFlowControl, "1", FALSE);
|
|
}
|
|
|
|
|
|
//
|
|
// Serial Speed
|
|
//
|
|
|
|
if (!pTG->SerialSpeedInitSet)
|
|
{
|
|
wsprintf(pTG->TmpSettings.szSmallTemp1, "%lu", (unsigned long) pTG->TmpSettings.dwSerialSpeed);
|
|
ProfileWriteString(dwKey, szFixSerialSpeed, pTG->TmpSettings.szSmallTemp1, FALSE);
|
|
}
|
|
else
|
|
{
|
|
wsprintf(pTG->TmpSettings.szSmallTemp1, "%lu", (unsigned long) pTG->SerialSpeedInit);
|
|
ProfileWriteString(dwKey, szSerialSpeedInit, pTG->TmpSettings.szSmallTemp1, FALSE);
|
|
}
|
|
|
|
if (pTG->TmpSettings.dwGot & fGOTFLAGS)
|
|
{
|
|
if (pTG->TmpSettings.dwFlags & fMDMSP_C1_NO_SYNC_IF_CMD)
|
|
{
|
|
ProfileWriteString(dwKey, szCL1_NO_SYNC_IF_CMD, "1", FALSE);
|
|
}
|
|
|
|
if (!(pTG->TmpSettings.dwFlags & fMDMSP_ANS_GOCLASS_TWICE))
|
|
{
|
|
ProfileWriteString(dwKey, szANS_GOCLASS_TWICE, "0", FALSE);
|
|
}
|
|
}
|
|
|
|
// uDontPurge==1 => save 1
|
|
// otherwise => save 0
|
|
wsprintf(pTG->TmpSettings.szSmallTemp1, "%lu", (unsigned long) (pTG->TmpSettings.uDontPurge==1)?1:0);
|
|
ProfileWriteString(dwKey, szDONT_PURGE, pTG->TmpSettings.szSmallTemp1, FALSE);
|
|
|
|
///////// Modem Caps...
|
|
// write out Classes, then Speeds
|
|
wsprintf(pTG->TmpSettings.szSmallTemp1, "%u", (unsigned) lpMdmCaps->uClasses);
|
|
ProfileWriteString(dwKey, szModemFaxClasses, pTG->TmpSettings.szSmallTemp1, FALSE);
|
|
|
|
// Classes 2 and 2.0
|
|
SaveCl2Settings(pTG, dwKey);
|
|
|
|
if(lpMdmCaps->uClasses & FAXCLASS1)
|
|
{
|
|
wsprintf(pTG->TmpSettings.szSmallTemp1, "%u", (unsigned) lpMdmCaps->uSendSpeeds);
|
|
ProfileWriteString(dwKey, szModemSendSpeeds, pTG->TmpSettings.szSmallTemp1, FALSE);
|
|
|
|
wsprintf(pTG->TmpSettings.szSmallTemp1, "%u", (unsigned) lpMdmCaps->uRecvSpeeds);
|
|
ProfileWriteString(dwKey, szModemRecvSpeeds, pTG->TmpSettings.szSmallTemp1, FALSE);
|
|
}
|
|
if (dwKey)
|
|
ProfileClose(dwKey);
|
|
|
|
return TRUE;
|
|
|
|
failure:
|
|
if (dwKey)
|
|
ProfileClose(dwKey);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL ReadModemClassFromRegistry (PThrdGlbl pTG)
|
|
{
|
|
|
|
UINT uTmp;
|
|
DWORD_PTR dwKey;
|
|
|
|
|
|
if ( ! (dwKey = ProfileOpen(pTG->FComModem.dwProfileID, pTG->FComModem.rgchKey, fREG_READ)))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Lets see what modem Class we will use
|
|
//
|
|
uTmp = ProfileGetInt(dwKey, szFixModemClass, 0, FALSE);
|
|
|
|
if (uTmp == 1)
|
|
{
|
|
pTG->ModemClass = MODEM_CLASS1;
|
|
}
|
|
else if (uTmp == 2)
|
|
{
|
|
pTG->ModemClass = MODEM_CLASS2;
|
|
}
|
|
else if (uTmp == 20)
|
|
{
|
|
pTG->ModemClass = MODEM_CLASS2_0;
|
|
}
|
|
|
|
if (dwKey)
|
|
ProfileClose(dwKey);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL SaveModemClass2Registry(PThrdGlbl pTG)
|
|
{
|
|
DWORD_PTR dwKey=0;
|
|
|
|
DEBUG_FUNCTION_NAME(("SaveModemClass2Registry"));
|
|
|
|
if (!(dwKey=ProfileOpen(pTG->FComModem.dwProfileID, pTG->FComModem.rgchKey,
|
|
fREG_CREATE | fREG_READ | fREG_WRITE)))
|
|
{
|
|
DebugPrintEx(DEBUG_ERR,"Couldn't get location of modem info.");
|
|
goto failure;
|
|
}
|
|
|
|
|
|
switch (pTG->ModemClass)
|
|
{
|
|
case MODEM_CLASS1 :
|
|
ProfileWriteString(dwKey, szFixModemClass, "1", TRUE);
|
|
break;
|
|
|
|
case MODEM_CLASS2 :
|
|
ProfileWriteString(dwKey, szFixModemClass, "2", TRUE);
|
|
break;
|
|
|
|
case MODEM_CLASS2_0 :
|
|
ProfileWriteString(dwKey, szFixModemClass, "20", TRUE);
|
|
break;
|
|
|
|
default:
|
|
DebugPrintEx(DEBUG_ERR,"pTG->ModemClass=%d", pTG->ModemClass);
|
|
ProfileWriteString(dwKey, szFixModemClass, "1", TRUE);
|
|
}
|
|
|
|
if (dwKey)
|
|
ProfileClose(dwKey);
|
|
|
|
return TRUE;
|
|
|
|
|
|
failure:
|
|
return FALSE;
|
|
|
|
|
|
}
|
|
|
|
|
|
BOOL SaveInf2Registry (PThrdGlbl pTG)
|
|
{
|
|
DWORD_PTR dwKey=0;
|
|
LPMODEMCAPS lpMdmCaps = pTG->TmpSettings.lpMdmCaps;
|
|
char KeyName[200];
|
|
DWORD_PTR dwKeyAdaptiveAnswer=0;
|
|
DWORD_PTR dwKeyAnswer=0;
|
|
DWORD i;
|
|
char szClass[10];
|
|
|
|
DEBUG_FUNCTION_NAME(("SaveInf2Registry"));
|
|
|
|
if (!(dwKey=ProfileOpen(pTG->FComModem.dwProfileID, pTG->FComModem.rgchKey,
|
|
fREG_CREATE | fREG_READ | fREG_WRITE)))
|
|
{
|
|
DebugPrintEx(DEBUG_ERR,"Couldn't get location of modem info.");
|
|
goto failure;
|
|
}
|
|
|
|
if (! pTG->ModemClass)
|
|
{
|
|
DebugPrintEx(DEBUG_ERR,"MODEM CLASS was not defined.");
|
|
}
|
|
|
|
switch (pTG->ModemClass)
|
|
{
|
|
case MODEM_CLASS1 :
|
|
sprintf(szClass, "Class1");
|
|
ProfileWriteString(dwKey, szFixModemClass, "1", TRUE);
|
|
break;
|
|
|
|
case MODEM_CLASS2 :
|
|
sprintf(szClass, "Class2");
|
|
ProfileWriteString(dwKey, szFixModemClass, "2", TRUE);
|
|
break;
|
|
|
|
case MODEM_CLASS2_0 :
|
|
sprintf(szClass, "Class2_0");
|
|
ProfileWriteString(dwKey, szFixModemClass, "20", TRUE);
|
|
break;
|
|
|
|
default:
|
|
sprintf(szClass, "Class1");
|
|
}
|
|
|
|
////// Modem Commands
|
|
if (pTG->TmpSettings.dwGot & fGOTCMD_Reset)
|
|
ProfileWriteString(dwKey, szResetCommand, pTG->TmpSettings.szReset, TRUE);
|
|
|
|
if (pTG->TmpSettings.dwGot & fGOTCMD_Setup)
|
|
ProfileWriteString(dwKey, szSetupCommand, pTG->TmpSettings.szSetup, TRUE);
|
|
|
|
if (pTG->TmpSettings.dwGot & fGOTCMD_PreExit)
|
|
ProfileWriteString(dwKey, szExitCommand , pTG->TmpSettings.szExit, TRUE);
|
|
|
|
if (pTG->TmpSettings.dwGot & fGOTCMD_PreDial)
|
|
ProfileWriteString(dwKey, szPreDialCommand , pTG->TmpSettings.szPreDial, TRUE);
|
|
|
|
if (pTG->TmpSettings.dwGot & fGOTCMD_PreAnswer)
|
|
ProfileWriteString(dwKey, szPreAnswerCommand, pTG->TmpSettings.szPreAnswer, TRUE);
|
|
|
|
|
|
//
|
|
// Adaptive Answer
|
|
//
|
|
|
|
if (pTG->AdaptiveAnswerEnable)
|
|
{
|
|
// create szClass key if it doesn't exist
|
|
|
|
sprintf(KeyName, "%s\\%s", pTG->FComModem.rgchKey, szClass);
|
|
|
|
dwKeyAdaptiveAnswer = ProfileOpen(pTG->FComModem.dwProfileID, KeyName, fREG_CREATE | fREG_READ | fREG_WRITE);
|
|
if (dwKeyAdaptiveAnswer == 0)
|
|
{
|
|
DebugPrintEx(DEBUG_ERR,"couldn't open szClass.");
|
|
goto failure;
|
|
}
|
|
|
|
ProfileClose(dwKeyAdaptiveAnswer);
|
|
|
|
// create Class\AdaptiveAnswer key if it doesn't exist
|
|
|
|
sprintf(KeyName, "%s\\%s\\AdaptiveAnswer", pTG->FComModem.rgchKey, szClass);
|
|
|
|
dwKeyAdaptiveAnswer = ProfileOpen(pTG->FComModem.dwProfileID, KeyName, fREG_CREATE | fREG_READ | fREG_WRITE);
|
|
if (dwKeyAdaptiveAnswer == 0)
|
|
{
|
|
DebugPrintEx(DEBUG_ERR,"couldn't open AdaptiveAnswer.");
|
|
goto failure;
|
|
}
|
|
|
|
// create Class1\AdaptiveAnswer\Answer key if it doesn't exist
|
|
|
|
sprintf(KeyName, "%s\\%s\\AdaptiveAnswer\\AnswerCommand", pTG->FComModem.rgchKey ,szClass);
|
|
|
|
dwKeyAnswer = ProfileOpen(pTG->FComModem.dwProfileID, KeyName, fREG_CREATE | fREG_READ | fREG_WRITE);
|
|
if (dwKeyAnswer == 0)
|
|
{
|
|
DebugPrintEx(DEBUG_ERR,"couldn't open AdaptiveAnswer\\AnswerCommand .");
|
|
goto failure;
|
|
}
|
|
|
|
for (i=0; i<pTG->AnswerCommandNum; i++)
|
|
{
|
|
sprintf (KeyName, "%d", i+1);
|
|
ProfileWriteString (dwKeyAnswer, KeyName , pTG->AnswerCommand[i], TRUE );
|
|
MemFree( pTG->AnswerCommand[i]);
|
|
pTG->AnswerCommand[i] = NULL;
|
|
}
|
|
pTG->AnswerCommandNum = 0;
|
|
ProfileClose(dwKeyAnswer);
|
|
|
|
// store the rest of the AdaptiveAnswer values
|
|
|
|
if (pTG->ModemResponseFaxDetect)
|
|
{
|
|
ProfileWriteString (dwKeyAdaptiveAnswer, szModemResponseFaxDetect, pTG->ModemResponseFaxDetect, FALSE);
|
|
MemFree( pTG->ModemResponseFaxDetect );
|
|
pTG->ModemResponseFaxDetect = NULL;
|
|
}
|
|
|
|
if (pTG->ModemResponseDataDetect)
|
|
{
|
|
ProfileWriteString (dwKeyAdaptiveAnswer, szModemResponseDataDetect, pTG->ModemResponseDataDetect, FALSE);
|
|
MemFree (pTG->ModemResponseDataDetect);
|
|
pTG->ModemResponseDataDetect = NULL;
|
|
}
|
|
|
|
if (pTG->SerialSpeedFaxDetect)
|
|
{
|
|
sprintf (KeyName, "%d", pTG->SerialSpeedFaxDetect);
|
|
ProfileWriteString (dwKeyAdaptiveAnswer, szSerialSpeedFaxDetect, KeyName, FALSE);
|
|
}
|
|
|
|
if (pTG->SerialSpeedDataDetect)
|
|
{
|
|
sprintf (KeyName, "%d", pTG->SerialSpeedDataDetect);
|
|
ProfileWriteString (dwKeyAdaptiveAnswer, szSerialSpeedDataDetect, KeyName, FALSE);
|
|
}
|
|
|
|
if (pTG->HostCommandFaxDetect)
|
|
{
|
|
ProfileWriteString (dwKeyAdaptiveAnswer, szHostCommandFaxDetect, pTG->HostCommandFaxDetect, TRUE);
|
|
MemFree( pTG->HostCommandFaxDetect);
|
|
pTG->HostCommandFaxDetect = NULL;
|
|
}
|
|
|
|
if (pTG->HostCommandDataDetect)
|
|
{
|
|
ProfileWriteString (dwKeyAdaptiveAnswer, szHostCommandDataDetect, pTG->HostCommandDataDetect,TRUE);
|
|
MemFree( pTG->HostCommandDataDetect);
|
|
pTG->HostCommandDataDetect = NULL;
|
|
}
|
|
|
|
if (pTG->ModemResponseFaxConnect)
|
|
{
|
|
ProfileWriteString (dwKeyAdaptiveAnswer, szModemResponseFaxConnect, pTG->ModemResponseFaxConnect, FALSE);
|
|
MemFree( pTG->ModemResponseFaxConnect);
|
|
pTG->ModemResponseFaxConnect = NULL;
|
|
}
|
|
|
|
if (pTG->ModemResponseDataConnect)
|
|
{
|
|
ProfileWriteString (dwKeyAdaptiveAnswer, szModemResponseDataConnect, pTG->ModemResponseDataConnect, FALSE);
|
|
MemFree(pTG->ModemResponseDataConnect);
|
|
pTG->ModemResponseDataConnect = NULL;
|
|
}
|
|
|
|
|
|
ProfileClose(dwKeyAdaptiveAnswer);
|
|
|
|
}
|
|
|
|
|
|
if (pTG->fEnableHardwareFlowControl)
|
|
{
|
|
ProfileWriteString (dwKey, szHardwareFlowControl, "1", FALSE);
|
|
}
|
|
|
|
|
|
//
|
|
// Serial Speed
|
|
//
|
|
|
|
if (pTG->SerialSpeedInitSet)
|
|
{
|
|
wsprintf(pTG->TmpSettings.szSmallTemp1, "%lu", (unsigned long) pTG->SerialSpeedInit);
|
|
ProfileWriteString(dwKey, szSerialSpeedInit, pTG->TmpSettings.szSmallTemp1, FALSE);
|
|
}
|
|
|
|
// Classes 2 and 2.0
|
|
SaveCl2Settings(pTG, dwKey);
|
|
|
|
if (dwKey)
|
|
ProfileClose(dwKey);
|
|
return TRUE;
|
|
|
|
|
|
|
|
failure:
|
|
if (dwKey)
|
|
ProfileClose(dwKey);
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOL imodem_alloc_tmp_strings(PThrdGlbl pTG)
|
|
{
|
|
WORD w;
|
|
LPSTR lpstr;
|
|
LPVOID lpv;
|
|
|
|
DEBUG_FUNCTION_NAME(("imodem_alloc_tmp_strings"));
|
|
|
|
w = TMPSTRINGBUFSIZE;
|
|
pTG->TmpSettings.hglb = (ULONG_PTR) MemAlloc(TMPSTRINGBUFSIZE);
|
|
|
|
if (!pTG->TmpSettings.hglb)
|
|
{
|
|
goto failure;
|
|
}
|
|
|
|
lpv = (LPVOID) (pTG->TmpSettings.hglb);
|
|
lpstr=(LPSTR)lpv;
|
|
if (!lpstr)
|
|
{
|
|
MemFree( (PVOID) pTG->TmpSettings.hglb);
|
|
pTG->TmpSettings.hglb=0;
|
|
goto failure;
|
|
}
|
|
pTG->TmpSettings.lpbBuf = (LPBYTE)lpstr;
|
|
|
|
_fmemset(lpstr, 0, TMPSTRINGBUFSIZE);
|
|
|
|
pTG->TmpSettings.szReset = lpstr; lpstr+=MAXCMDSIZE;
|
|
pTG->TmpSettings.szResetGenerated = lpstr; lpstr+=MAXCMDSIZE;
|
|
pTG->TmpSettings.szSetup = lpstr; lpstr+=MAXCMDSIZE;
|
|
pTG->TmpSettings.szSetupGenerated = lpstr; lpstr+=MAXCMDSIZE;
|
|
pTG->TmpSettings.szExit = lpstr; lpstr+=MAXCMDSIZE;
|
|
pTG->TmpSettings.szPreDial = lpstr; lpstr+=MAXCMDSIZE;
|
|
pTG->TmpSettings.szPreAnswer = lpstr; lpstr+=MAXCMDSIZE;
|
|
pTG->TmpSettings.szIDCmd = lpstr; lpstr+=MAXCMDSIZE;
|
|
pTG->TmpSettings.szID = lpstr; lpstr+=MAXIDSIZE;
|
|
pTG->TmpSettings.szResponseBuf = lpstr; lpstr+=RESPONSEBUFSIZE;
|
|
pTG->TmpSettings.szSmallTemp1 = lpstr; lpstr+=SMALLTEMPSIZE;
|
|
pTG->TmpSettings.szSmallTemp2 = lpstr; lpstr+=SMALLTEMPSIZE;
|
|
|
|
pTG->TmpSettings.dwGot=0;
|
|
|
|
if ( ((LPSTR)lpv+TMPSTRINGBUFSIZE) < lpstr)
|
|
{
|
|
MemFree( (PVOID) pTG->TmpSettings.hglb);
|
|
pTG->TmpSettings.hglb=0;
|
|
goto failure;
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
failure:
|
|
|
|
DebugPrintEx(DEBUG_ERR,"MyAlloc/MyLock failed!");
|
|
return FALSE;
|
|
}
|
|
|
|
void imodem_free_tmp_strings(PThrdGlbl pTG)
|
|
{
|
|
if (pTG->TmpSettings.hglb)
|
|
{
|
|
MemFree( (PVOID) pTG->TmpSettings.hglb);
|
|
}
|
|
_fmemset(&pTG->TmpSettings, 0, sizeof(pTG->TmpSettings));
|
|
}
|
|
|
|
void imodem_clear_tmp_settings(PThrdGlbl pTG)
|
|
{
|
|
_fmemset(pTG->TmpSettings.lpMdmCaps, 0, sizeof(MODEMCAPS));
|
|
pTG->TmpSettings.dwGot=0;
|
|
pTG->TmpSettings.uDontPurge=0;
|
|
pTG->TmpSettings.dwSerialSpeed=0;
|
|
pTG->TmpSettings.dwFlags=0;
|
|
_fmemset(pTG->TmpSettings.lpbBuf, 0, TMPSTRINGBUFSIZE);
|
|
}
|
|
|
|
BOOL
|
|
imodem_list_get_str
|
|
(
|
|
PThrdGlbl pTG,
|
|
ULONG_PTR KeyList[10],
|
|
LPSTR lpszName,
|
|
LPSTR lpszCmdBuf,
|
|
UINT cbMax,
|
|
BOOL fCmd
|
|
)
|
|
{
|
|
int i;
|
|
int Num=0;
|
|
BOOL bRet=0;
|
|
|
|
|
|
for (i=0; i<10; i++)
|
|
{
|
|
if (KeyList[i] == 0)
|
|
{
|
|
Num = i-1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
for (i=Num; i>=0; i--)
|
|
{
|
|
if ( bRet = imodem_get_str(pTG, KeyList[i], lpszName, lpszCmdBuf, cbMax, fCmd) )
|
|
{
|
|
return bRet;
|
|
}
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
BOOL imodem_get_str
|
|
(
|
|
PThrdGlbl pTG,
|
|
ULONG_PTR dwKey,
|
|
LPSTR lpszName,
|
|
LPSTR lpszCmdBuf,
|
|
UINT cbMax,
|
|
BOOL fCmd
|
|
)
|
|
{
|
|
UINT uLen2;
|
|
char *pc = "bogus";
|
|
|
|
*lpszCmdBuf=0;
|
|
|
|
uLen2 = ProfileGetString(dwKey, lpszName,pc, lpszCmdBuf, cbMax-1);
|
|
if (uLen2)
|
|
{
|
|
if (!_fstrcmp(lpszCmdBuf, pc))
|
|
{
|
|
*lpszCmdBuf=0; return FALSE;
|
|
}
|
|
if (fCmd)
|
|
EndWithCR(lpszCmdBuf, (USHORT)uLen2);
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL iModemCopyOEMInfo(PThrdGlbl pTG)
|
|
{
|
|
|
|
return ProfileCopyTree( DEF_BASEKEY,
|
|
pTG->FComModem.rgchKey,
|
|
OEM_BASEKEY,
|
|
pTG->lpszUnimodemFaxKey);
|
|
|
|
}
|
|
|
|
|
|
|
|
#define MASKOFFV17 0x03
|
|
|
|
void SmashCapsAccordingToSettings(PThrdGlbl pTG)
|
|
{
|
|
// INI file has already been read.
|
|
|
|
DEBUG_FUNCTION_NAME(("SmashCapsAccordingToSettings"));
|
|
// If !fV17Enable then smash the V17 bits of the Capabilities
|
|
if(!pTG->Inst.ProtParams.fEnableV17Send)
|
|
{
|
|
DebugPrintEx(DEBUG_WRN,"Masking off V.17 send capabilities");
|
|
pTG->FComModem.CurrMdmCaps.uSendSpeeds &= MASKOFFV17;
|
|
}
|
|
|
|
if(!pTG->Inst.ProtParams.fEnableV17Recv)
|
|
{
|
|
DebugPrintEx(DEBUG_WRN,"Masking off V.17 receive capabilities");
|
|
pTG->FComModem.CurrMdmCaps.uRecvSpeeds &= MASKOFFV17;
|
|
}
|
|
|
|
//
|
|
// commented out RSL. We run at 19200. Nowhere in awmodem.inf have I seen FixSerialSpeed clause.
|
|
//
|
|
|
|
DebugPrintEx( DEBUG_MSG,
|
|
"uSendSpeeds=%x uRecvSpeeds=%x",
|
|
pTG->FComModem.CurrMdmCaps.uSendSpeeds,
|
|
pTG->FComModem.CurrMdmCaps.uRecvSpeeds);
|
|
|
|
}
|
|
|
|
int
|
|
SearchNewInfFile
|
|
(
|
|
PThrdGlbl pTG,
|
|
char *Key1,
|
|
char *Key2,
|
|
BOOL fRead
|
|
)
|
|
{
|
|
|
|
char szInfSection[] = "SecondKey=";
|
|
DWORD lenNewInf;
|
|
int RetCode = FALSE;
|
|
char Buffer[400]; // to hold lpToken=lpValue string
|
|
char *lpCurrent;
|
|
char *lpStartSection;
|
|
char *lpTmp;
|
|
char *lpToken;
|
|
char *lpValue;
|
|
|
|
|
|
ToCaps(Key1);
|
|
|
|
if (Key2)
|
|
{
|
|
ToCaps(Key2);
|
|
}
|
|
|
|
pTG->AnswerCommandNum = 0;
|
|
|
|
if ( ( lenNewInf = strlen(szAdaptiveInf) ) == 0 )
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
//
|
|
// Loop thru all segments.
|
|
// Each segment starts with InfPath=
|
|
//
|
|
|
|
lpCurrent = szAdaptiveInf;
|
|
|
|
do
|
|
{
|
|
// find InfPath
|
|
lpStartSection = strstr (lpCurrent, szResponsesKeyName);
|
|
if (! lpStartSection)
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
lpTmp = strchr (lpStartSection, '\r' );
|
|
if (!lpTmp)
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
// compare Key1
|
|
if ( strlen(Key1) != (lpTmp - lpStartSection - strlen(szResponsesKeyName) ) )
|
|
{
|
|
lpCurrent = lpTmp;
|
|
continue;
|
|
}
|
|
|
|
if ( memcmp (lpStartSection+strlen(szResponsesKeyName),
|
|
Key1,
|
|
(ULONG)(lpTmp - lpStartSection - strlen(szResponsesKeyName) ) ) != 0 )
|
|
{
|
|
lpCurrent = lpTmp;
|
|
continue;
|
|
}
|
|
|
|
// find InfSection
|
|
|
|
lpCurrent = lpTmp;
|
|
|
|
if (Key2)
|
|
{
|
|
lpStartSection = strstr (lpCurrent, szInfSection);
|
|
if (! lpStartSection)
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
lpTmp = strchr (lpStartSection, '\r' );
|
|
if (!lpTmp)
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
// compare Key2
|
|
|
|
if ( strlen(Key2) != (lpTmp - lpStartSection - strlen(szInfSection) ) )
|
|
{
|
|
lpCurrent = lpTmp;
|
|
continue;
|
|
}
|
|
|
|
if ( memcmp (lpStartSection+strlen(szInfSection),
|
|
Key2,
|
|
(ULONG)(lpTmp - lpStartSection - strlen(szInfSection)) ) != 0 )
|
|
{
|
|
lpCurrent = lpTmp;
|
|
continue;
|
|
}
|
|
|
|
lpCurrent = lpTmp;
|
|
|
|
}
|
|
|
|
//
|
|
// both keys matched. Go get settings and return
|
|
//
|
|
|
|
do
|
|
{
|
|
lpCurrent = strchr (lpCurrent, '\r' );
|
|
if (!lpCurrent)
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
lpCurrent += 2;
|
|
|
|
|
|
// find next setting inside the matching section
|
|
lpToken = lpCurrent;
|
|
|
|
lpCurrent = strchr (lpCurrent, '=' );
|
|
if (!lpCurrent)
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
lpTmp = strchr (lpToken, '\r' );
|
|
if (!lpTmp)
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
if (lpCurrent > lpTmp)
|
|
{
|
|
// empty string
|
|
lpCurrent = lpTmp;
|
|
continue;
|
|
}
|
|
|
|
|
|
lpValue = ++lpCurrent;
|
|
|
|
lpTmp = strchr (lpValue, '\r' );
|
|
if (!lpTmp)
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
// we parsed the string. Now get it to the Buffer
|
|
|
|
if (lpTmp - lpToken > sizeof (Buffer) )
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
memcpy(Buffer, lpToken, (ULONG)(lpTmp - lpToken));
|
|
|
|
Buffer[lpValue -lpToken - 1] = 0;
|
|
Buffer[lpTmp - lpToken] = 0;
|
|
|
|
lpValue = &Buffer[lpValue - lpToken];
|
|
lpToken = Buffer;
|
|
|
|
pTG->fAdaptiveRecordFound = 1;
|
|
|
|
|
|
if ( my_strcmp(lpToken, szAdaptiveAnswerEnable) )
|
|
{
|
|
pTG->AdaptiveAnswerEnable = atoi (lpValue);
|
|
}
|
|
else if ( my_strcmp(lpToken, szAdaptiveRecordUnique) )
|
|
{
|
|
pTG->fAdaptiveRecordUnique = atoi (lpValue);
|
|
}
|
|
else if ( my_strcmp(lpToken, szAdaptiveCodeId) )
|
|
{
|
|
pTG->AdaptiveCodeId = atoi (lpValue);
|
|
if ( ! fRead )
|
|
{
|
|
goto exit;
|
|
}
|
|
}
|
|
else if ( my_strcmp(lpToken, szFaxClass) )
|
|
{
|
|
;
|
|
}
|
|
else if ( my_strcmp(lpToken, szHardwareFlowControl) )
|
|
{
|
|
pTG->fEnableHardwareFlowControl = atoi (lpValue);
|
|
}
|
|
else if ( my_strcmp(lpToken, szSerialSpeedInit) )
|
|
{
|
|
pTG->SerialSpeedInit = (USHORT)atoi (lpValue);
|
|
pTG->SerialSpeedInitSet = 1;
|
|
}
|
|
else if ( my_strcmp(lpToken, szResetCommand) )
|
|
{
|
|
sprintf ( pTG->TmpSettings.szReset, "%s\r", lpValue);
|
|
pTG->TmpSettings.dwGot |= fGOTCMD_Reset;
|
|
}
|
|
else if ( my_strcmp(lpToken, szSetupCommand) )
|
|
{
|
|
sprintf ( pTG->TmpSettings.szSetup, "%s\r", lpValue);
|
|
pTG->TmpSettings.dwGot |= fGOTCMD_Setup;
|
|
}
|
|
else if ( my_strcmp(lpToken, szAnswerCommand) )
|
|
{
|
|
if (pTG->AnswerCommandNum >= MAX_ANSWER_COMMANDS)
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
if (NULL != (pTG->AnswerCommand[pTG->AnswerCommandNum] = MemAlloc( strlen(lpValue) + 1)))
|
|
{
|
|
strcpy ( pTG->AnswerCommand[pTG->AnswerCommandNum], lpValue);
|
|
pTG->AnswerCommandNum++;
|
|
}
|
|
else
|
|
{
|
|
goto bad_exit;
|
|
}
|
|
}
|
|
else if ( my_strcmp(lpToken, szModemResponseFaxDetect) )
|
|
{
|
|
if (NULL != (pTG->ModemResponseFaxDetect = MemAlloc( strlen(lpValue) + 1)))
|
|
strcpy ( pTG->ModemResponseFaxDetect, lpValue);
|
|
else
|
|
goto bad_exit;
|
|
}
|
|
else if ( my_strcmp(lpToken, szModemResponseDataDetect) )
|
|
{
|
|
if (NULL != (pTG->ModemResponseDataDetect = MemAlloc( strlen(lpValue) + 1)))
|
|
strcpy ( pTG->ModemResponseDataDetect, lpValue);
|
|
else
|
|
goto bad_exit;
|
|
}
|
|
else if ( my_strcmp(lpToken, szSerialSpeedFaxDetect) )
|
|
{
|
|
pTG->SerialSpeedFaxDetect = (USHORT)atoi (lpValue);
|
|
}
|
|
else if ( my_strcmp(lpToken, szSerialSpeedDataDetect) )
|
|
{
|
|
pTG->SerialSpeedDataDetect = (USHORT)atoi (lpValue);
|
|
}
|
|
else if ( my_strcmp(lpToken, szHostCommandFaxDetect) )
|
|
{
|
|
if (NULL != (pTG->HostCommandFaxDetect = MemAlloc( strlen(lpValue) + 1)))
|
|
strcpy ( pTG->HostCommandFaxDetect, lpValue);
|
|
else
|
|
goto bad_exit;
|
|
}
|
|
else if ( my_strcmp(lpToken, szHostCommandDataDetect) )
|
|
{
|
|
if (NULL != (pTG->HostCommandDataDetect = MemAlloc( strlen(lpValue) + 1)))
|
|
strcpy ( pTG->HostCommandDataDetect, lpValue);
|
|
else
|
|
goto bad_exit;
|
|
}
|
|
else if ( my_strcmp(lpToken, szModemResponseFaxConnect) )
|
|
{
|
|
if (NULL != (pTG->ModemResponseFaxConnect = MemAlloc( strlen(lpValue) + 1)))
|
|
strcpy ( pTG->ModemResponseFaxConnect, lpValue);
|
|
else
|
|
goto bad_exit;
|
|
}
|
|
else if ( my_strcmp(lpToken, szModemResponseDataConnect) )
|
|
{
|
|
if (NULL != (pTG->ModemResponseDataConnect = MemAlloc( strlen(lpValue) + 1)))
|
|
strcpy ( pTG->ModemResponseDataConnect, lpValue);
|
|
else
|
|
goto bad_exit;
|
|
}
|
|
else if ( my_strcmp(lpToken, szResponsesKeyName2) )
|
|
{
|
|
RetCode = TRUE;
|
|
goto exit;
|
|
}
|
|
|
|
}
|
|
while ( 1 ); // section loop
|
|
}
|
|
while ( 1 ); // file loop
|
|
return (FALSE);
|
|
|
|
bad_exit:
|
|
CleanModemInfStrings (pTG);
|
|
exit:
|
|
return (RetCode);
|
|
|
|
}
|
|
|
|
|
|
VOID
|
|
CleanModemInfStrings (
|
|
PThrdGlbl pTG
|
|
)
|
|
|
|
{
|
|
DWORD i;
|
|
|
|
for (i=0; i<pTG->AnswerCommandNum; i++) {
|
|
if (pTG->AnswerCommand[i]) {
|
|
MemFree( pTG->AnswerCommand[i]);
|
|
pTG->AnswerCommand[i] = NULL;
|
|
}
|
|
}
|
|
|
|
pTG->AnswerCommandNum = 0;
|
|
|
|
if (pTG->ModemResponseFaxDetect) {
|
|
MemFree( pTG->ModemResponseFaxDetect );
|
|
pTG->ModemResponseFaxDetect = NULL;
|
|
}
|
|
|
|
if (pTG->ModemResponseDataDetect) {
|
|
MemFree (pTG->ModemResponseDataDetect);
|
|
pTG->ModemResponseDataDetect = NULL;
|
|
}
|
|
|
|
|
|
if (pTG->HostCommandFaxDetect) {
|
|
MemFree( pTG->HostCommandFaxDetect);
|
|
pTG->HostCommandFaxDetect = NULL;
|
|
}
|
|
|
|
if (pTG->HostCommandDataDetect) {
|
|
MemFree( pTG->HostCommandDataDetect);
|
|
pTG->HostCommandDataDetect = NULL;
|
|
}
|
|
|
|
|
|
if (pTG->ModemResponseFaxConnect) {
|
|
MemFree( pTG->ModemResponseFaxConnect);
|
|
pTG->ModemResponseFaxConnect = NULL;
|
|
}
|
|
|
|
if (pTG->ModemResponseDataConnect) {
|
|
MemFree(pTG->ModemResponseDataConnect);
|
|
pTG->ModemResponseDataConnect = NULL;
|
|
}
|
|
|
|
}
|
|
|