Source code of Windows XP (NT5)
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.

3341 lines
102 KiB

  1. /***************************************************************************
  2. Name : IDENTIFY.C
  3. Comment : Identifying modems
  4. Copyright (c) Microsoft Corp. 1991, 1992, 1993
  5. Revision Log
  6. Num Date Name Description
  7. --- -------- ---------- -----------------------------------------------
  8. ***************************************************************************/
  9. #include "prep.h"
  10. #include "modemint.h"
  11. //#include "fcomint.h"
  12. #include "fdebug.h"
  13. #include "awmodem.h"
  14. #include "adaptive.h"
  15. ///RSL
  16. #include "glbproto.h"
  17. #define BIGTEMPSIZE 250
  18. #define faxTlog(m) DEBUGMSG(ZONE_ID, m)
  19. #define faxT2log(m) DEBUGMSG(ZONE_ID2, m)
  20. #define FILEID FILEID_IDENTIFY
  21. #include "inifile.h"
  22. char szModemFaxClasses[] = "ModemFaxClasses";
  23. char szModemSendSpeeds[] = "ModemSendSpeeds";
  24. char szModemRecvSpeeds[] = "ModemRecvSpeeds";
  25. char szModemId[] = "ModemId";
  26. char szModemIdCmd[] = "ModemIdCmd";
  27. char szClass0ModemId[] = "Class0ModemId";
  28. char szClass2ModemId[] = "Class2ModemId";
  29. char szClass20ModemId[] = "Class2.0ModemId";
  30. char szResetCommand[] = "ResetCommand";
  31. char szSetupCommand[] = "SetupCommand";
  32. char szExitCommand[] = "ExitCommand";
  33. char szPreDialCommand[] = "PreDialCommand";
  34. char szPreAnswerCommand[]= "PreAnswerCommand";
  35. // RSL new UNIMODEM INF settings (FAX GENERIC)
  36. char szHardwareFlowControl[] = "HardwareFlowControl";
  37. char szSerialSpeedInit[] = "SerialSpeedInit";
  38. char szSerialSpeedConnect[] = "SerialSpeedConnect";
  39. char szAdaptiveAnswerEnable[] = "AdaptiveAnswerEnable";
  40. // new ADAPTIVE INF file (FAX ADAPTIVE)
  41. char szResponsesKeyName[] = "ResponsesKeyName=";
  42. char szResponsesKeyName2[] = "ResponsesKeyName";
  43. char szAdaptiveRecordUnique[] = "AdaptiveRecordUnique";
  44. char szAdaptiveCodeId[] = "AdaptiveCodeId";
  45. char szFaxClass[] = "FaxClass";
  46. char szAnswerCommand[] = "AnswerCommand";
  47. char szModemResponseFaxDetect[] = "ModemResponseFaxDetect";
  48. char szModemResponseDataDetect[] = "ModemResponseDataDetect";
  49. char szSerialSpeedFaxDetect[] = "SerialSpeedFaxDetect";
  50. char szSerialSpeedDataDetect[] = "SerialSpeedDataDetect";
  51. char szHostCommandFaxDetect[] = "HostCommandFaxDetect";
  52. char szHostCommandDataDetect[] = "HostCommandDataDetect";
  53. char szModemResponseFaxConnect[] = "ModemResponseFaxConnect";
  54. char szModemResponseDataConnect[] = "ModemResponseDataConnect";
  55. // how was the Modem Key created
  56. char szModemKeyCreationId[] = "ModemKeyCreationId";
  57. #define NUM_CL0IDCMDS 7
  58. #define NUM_CL2IDCMDS 3
  59. #define NUM_CL20IDCMDS 3
  60. #define LEN_CL0IDCMDS 5
  61. #define LEN_CL2IDCMDS 9
  62. #define LEN_CL20IDCMDS 8
  63. USHORT iModemFigureOutCmdsExt(PThrdGlbl pTG);
  64. BOOL iModemCopyOEMInfo(PThrdGlbl pTG);
  65. void SmashCapsAccordingToSettings(PThrdGlbl pTG);
  66. NPSTR szClass0IdCmds[NUM_CL0IDCMDS] =
  67. {
  68. "ATI0\r",
  69. "ATI1\r",
  70. "ATI2\r",
  71. "ATI3\r",
  72. "ATI4\r",
  73. "ATI5\r",
  74. "ATI6\r"
  75. };
  76. NPSTR szClass2IdCmds[NUM_CL2IDCMDS] =
  77. {
  78. "AT+FMFR?\r",
  79. "AT+FMDL?\r",
  80. "AT+FREV?\r"
  81. };
  82. NPSTR szClass20IdCmds[NUM_CL20IDCMDS] =
  83. {
  84. "AT+FMI?\r",
  85. "AT+FMM?\r",
  86. "AT+FMR?\r"
  87. };
  88. typedef struct {
  89. USHORT uGoClass, uNum, uLen;
  90. NPSTR *CmdTable;
  91. NPSTR szIniEntry;
  92. } GETIDSTRUCT, near* NPGETIDSTRUCT;
  93. GETIDSTRUCT GetIdTable[3] =
  94. {
  95. { 0, NUM_CL0IDCMDS, LEN_CL0IDCMDS, szClass0IdCmds, szClass0ModemId },
  96. { 2, NUM_CL2IDCMDS, LEN_CL2IDCMDS, szClass2IdCmds, szClass2ModemId },
  97. { GOCLASS2_0, NUM_CL20IDCMDS, LEN_CL20IDCMDS, szClass20IdCmds, szClass20ModemId }
  98. };
  99. #define MAXCMDSIZE 128
  100. #define MAXIDSIZE 128
  101. #define RESPONSEBUFSIZE 256
  102. #define SMALLTEMPSIZE 80
  103. #define TMPSTRINGBUFSIZE (6*MAXCMDSIZE+MAXIDSIZE+RESPONSEBUFSIZE+2*SMALLTEMPSIZE+10)
  104. // Enough space for all the lpszs below.
  105. BOOL imodem_alloc_tmp_strings(PThrdGlbl pTG);
  106. void imodem_free_tmp_strings(PThrdGlbl pTG);
  107. void imodem_clear_tmp_settings(PThrdGlbl pTG);
  108. BOOL
  109. imodem_list_get_str(
  110. PThrdGlbl pTG,
  111. ULONG_PTR KeyList[10],
  112. LPSTR lpszName,
  113. LPSTR lpszCmdBuf,
  114. UINT cbMax,
  115. BOOL fCmd);
  116. BOOL imodem_get_str(PThrdGlbl pTG, ULONG_PTR dwKey, LPSTR lpszName, LPSTR lpszCmdBuf, UINT cbMax,
  117. BOOL fCmd);
  118. BOOL SearchInfFile(PThrdGlbl pTG, LPSTR lpstrFile, LPSTR lpstr1, LPSTR lpstr2, LPSTR lpstr3, DWORD_PTR dwLocalKey);
  119. void CheckAwmodemInf(PThrdGlbl pTG);
  120. void ToCaps(LPBYTE lpb);
  121. BOOL iModemGetCurrentModemInfo(PThrdGlbl pTG);
  122. BOOL iModemSaveCurrentModemInfo(PThrdGlbl pTG);
  123. UINT iModemGetUserFeedback(PThrdGlbl pTG, DWORD dwLineID, DWORD dwLineIDType);
  124. #ifndef USE_REGISTRY
  125. BOOL iModemExpandKey(PThrdGlbl pTG, DWORD dwKey, LPSTR FAR *lplpszKey, LPSTR FAR *lplpszProfileName);
  126. #endif
  127. USHORT EndWithCR( LPSTR sz, USHORT uLen)
  128. {
  129. if(uLen)
  130. {
  131. // Check if the string is terminated with a \r
  132. if(sz[uLen-1] != '\r')
  133. {
  134. // add a \r
  135. sz[uLen++] = '\r';
  136. sz[uLen] = 0;
  137. }
  138. }
  139. return uLen;
  140. }
  141. BOOL
  142. RemoveCR (
  143. LPSTR sz
  144. )
  145. {
  146. DWORD len;
  147. if (!sz) {
  148. return FALSE;
  149. }
  150. len = strlen(sz);
  151. if (len == 0) {
  152. return FALSE;
  153. }
  154. if (sz[len-1] == '\r') {
  155. sz[len-1] = 0;
  156. }
  157. return TRUE;
  158. }
  159. USHORT GetIdResp(PThrdGlbl pTG, LPSTR szSend, USHORT uSendLen, LPBYTE lpbRespOut, USHORT cbMaxOut)
  160. {
  161. USHORT uRespLen;
  162. (MyDebugPrint(pTG, LOG_ALL, "Want Id for (%s)\r\n", (LPSTR)szSend));
  163. pTG->fMegaHertzHack = TRUE;
  164. OfflineDialog2(pTG, (LPSTR)szSend, uSendLen, cbszOK, cbszERROR);
  165. pTG->fMegaHertzHack=FALSE;
  166. // sometimes we don't get the OK so try to parse what we got anyway
  167. (MyDebugPrint(pTG, LOG_ALL, "LastLine = (%s)\r\n ", (LPSTR)(&(pTG->FComModem.bLastReply))));
  168. uRespLen = min(cbMaxOut, _fstrlen(pTG->FComModem.bLastReply));
  169. _fmemcpy(lpbRespOut, pTG->FComModem.bLastReply, uRespLen);
  170. lpbRespOut[uRespLen] = 0; // zero terminate the string
  171. return uRespLen;
  172. }
  173. USHORT GetIdForClass(PThrdGlbl pTG, NPGETIDSTRUCT npgids, LPBYTE lpbOut, USHORT cbMaxOut,
  174. LPBYTE lpbLongestId, USHORT cbMaxLongestId, LPBYTE lpbLongestCmd)
  175. {
  176. USHORT i, j, k, uRet, uLen, uLenLong, iLong;
  177. LPBYTE lpbLong;
  178. BG_CHK(lpbOut && cbMaxOut>2);
  179. cbMaxOut -= 2; // make space for trailing ; and \0
  180. if(lpbLongestId)
  181. cbMaxLongestId -= 1; // make space for trailing \0
  182. uLen=0;
  183. if(npgids->uGoClass)
  184. {
  185. if(!iiModemGoClass(pTG, npgids->uGoClass, 0))
  186. {
  187. ERRMSG(("<<ERROR>> GoClass %d failed\r\n", npgids->uGoClass));
  188. goto done;
  189. }
  190. }
  191. for(lpbLong=NULL, uLenLong=0, i=0; i<npgids->uNum; i++)
  192. {
  193. uRet = GetIdResp(pTG, npgids->CmdTable[i], npgids->uLen, lpbOut+uLen, (USHORT)(cbMaxOut-uLen));
  194. // find longest ID among ATI0 thru 3 only!
  195. if(i<=3 && uLenLong < cbMaxLongestId && uRet > uLenLong)
  196. {
  197. uLenLong = min(uRet, cbMaxLongestId);
  198. lpbLong = lpbOut + uLen;
  199. iLong = i;
  200. }
  201. uLen += uRet;
  202. lpbOut[uLen++] = ';';
  203. }
  204. lpbOut[uLen] = 0;
  205. if(lpbLongestId && lpbLongestCmd && cbMaxLongestId && lpbLong && uLenLong)
  206. {
  207. _fmemcpy(lpbLongestId, lpbLong, uLenLong);
  208. lpbLongestId[uLenLong] = 0;
  209. _fmemcpy(lpbLongestCmd, npgids->CmdTable[iLong], npgids->uLen);
  210. lpbLongestCmd[npgids->uLen] = 0;
  211. TRACE(("LongestId (%s\r\n)-->(%s)\r\n", (LPSTR)lpbLongestCmd, (LPSTR)lpbLongestId));
  212. }
  213. // strip non-prinatbles. *AFTER* extracting the ModemId string!!
  214. for(j=0, k=0; j<uLen; j++)
  215. {
  216. if(lpbOut[j] >= 32 && lpbOut[j] <= 127)
  217. lpbOut[k++] = lpbOut[j];
  218. }
  219. uLen = k;
  220. lpbOut[uLen] = 0;
  221. TRACE(("Class%dId (%s)\r\n", npgids->uGoClass, (LPSTR)lpbOut));
  222. done:
  223. if(npgids->uGoClass)
  224. iiModemGoClass(pTG, 0, 0);
  225. return uLen;
  226. }
  227. void iModemGetWriteIds(PThrdGlbl pTG, BOOL fGotOEMInfo)
  228. {
  229. // As with iModemFigureOutCmds and iModemGetCaps, we selectively
  230. // detect ID's taking into account OEM info that's already read in...
  231. USHORT uLen1, uLen2, uLen3;
  232. DWORD_PTR dwKey=0;
  233. LPSTR lpstr1 = 0, lpstr2 = 0, lpstr3 = 0;
  234. USHORT uClasses = pTG->TmpSettings.lpMdmCaps->uClasses;
  235. uLen1 = uLen2 = uLen3 = 0;
  236. if (!(dwKey=ProfileOpen(pTG->FComModem.dwProfileID, pTG->FComModem.rgchKey,
  237. fREG_CREATE | fREG_READ | fREG_WRITE)))
  238. {
  239. ERRMSG(("<<ERROR>> Couldn't get location of modem info.\n\r"));
  240. BG_CHK(FALSE);
  241. goto end;
  242. }
  243. if (pTG->TmpSettings.dwGot & fGOTPARM_IDCMD)
  244. {
  245. int i=0;
  246. // We have a null ID ...
  247. if (!pTG->TmpSettings.szIDCmd[0])
  248. {
  249. BG_CHK(!pTG->TmpSettings.szID[0]);
  250. goto SaveIDandCMD;
  251. }
  252. // We are to detect the ID
  253. while(i++<2)
  254. {
  255. pTG->TmpSettings.szID[0]=0;
  256. pTG->TmpSettings.szResponseBuf[0]=0;
  257. GetIdResp(pTG, pTG->TmpSettings.szIDCmd,
  258. (USHORT) _fstrlen(pTG->TmpSettings.szIDCmd),
  259. pTG->TmpSettings.szID, MAXIDSIZE);
  260. GetIdResp(pTG, pTG->TmpSettings.szIDCmd,
  261. (USHORT)_fstrlen(pTG->TmpSettings.szIDCmd),
  262. pTG->TmpSettings.szResponseBuf, MAXIDSIZE);
  263. if (!_fstrcmp(pTG->TmpSettings.szID, pTG->TmpSettings.szResponseBuf)) break;
  264. }
  265. if (i>=3 || !pTG->TmpSettings.szID[0])
  266. {
  267. ERRMSG(("<<ERROR>> Can't get matching ID for supplied IDCMD: %s\r\n",
  268. (LPSTR) pTG->TmpSettings.szIDCmd));
  269. pTG->TmpSettings.szIDCmd[0]=pTG->TmpSettings.szID[0]=0;
  270. }
  271. else
  272. {
  273. ERRMSG((" OEM IDCmd=%s --> %s\r\n",
  274. (LPSTR) pTG->TmpSettings.szIDCmd,
  275. (LPSTR) pTG->TmpSettings.szID));
  276. }
  277. pTG->TmpSettings.dwGot |= (fGOTPARM_IDCMD | fGOTPARM_ID);
  278. goto SaveIDandCMD;
  279. }
  280. // write ModemId first, then ModemIdCmd
  281. // the lpszOemIDCmd and lpszOemID above).
  282. pTG->TmpSettings.szID[0]=0;
  283. lpstr1 = pTG->TmpSettings.szResponseBuf;
  284. uLen1 = GetIdForClass(pTG, &GetIdTable[0], lpstr1,
  285. RESPONSEBUFSIZE, pTG->TmpSettings.szID, MAXIDSIZE,
  286. pTG->TmpSettings.szIDCmd);
  287. lpstr1[uLen1] = 0;
  288. if (pTG->TmpSettings.szID[0]) pTG->TmpSettings.dwGot |= (fGOTPARM_IDCMD|fGOTPARM_ID);
  289. // then the Class0, 2, 2.0 ID strings
  290. ProfileWriteString(dwKey, GetIdTable[0].szIniEntry, lpstr1, FALSE);
  291. if(uClasses & FAXCLASS2)
  292. {
  293. BG_CHK(pTG->TmpSettings.szResponseBuf[uLen1] == 0);
  294. lpstr2 = pTG->TmpSettings.szResponseBuf + uLen1 + 1;
  295. BG_CHK(uLen1 + 1 < RESPONSEBUFSIZE);
  296. uLen2 = GetIdForClass(pTG, &GetIdTable[1], lpstr2,
  297. (USHORT)(RESPONSEBUFSIZE-uLen1-1), 0, 0, 0);
  298. lpstr2[uLen2] = 0;
  299. ProfileWriteString(dwKey, GetIdTable[1].szIniEntry, lpstr2, FALSE);
  300. }
  301. if(uClasses & FAXCLASS2_0)
  302. {
  303. BG_CHK(pTG->TmpSettings.szResponseBuf[uLen1] == 0);
  304. BG_CHK(uLen2==0 || pTG->TmpSettings.szResponseBuf[uLen1+uLen2+1] == 0);
  305. BG_CHK(uLen1 + uLen2 + 2 < RESPONSEBUFSIZE);
  306. lpstr3 = pTG->TmpSettings.szResponseBuf + uLen1 + uLen2 + 2;
  307. uLen3 = GetIdForClass(pTG, &GetIdTable[2], lpstr3, (USHORT)((RESPONSEBUFSIZE)-uLen1-uLen2-2), 0, 0, 0);
  308. lpstr3[uLen3] = 0;
  309. ProfileWriteString(dwKey, GetIdTable[2].szIniEntry, lpstr3, FALSE);
  310. }
  311. ToCaps(lpstr1);
  312. ToCaps(lpstr2);
  313. ToCaps(lpstr3);
  314. TRACE(("Got Ids (%s)\r\n(%s)\r\n(%s)\r\n",
  315. ((LPSTR)(lpstr1 ? lpstr1 : "null")),
  316. ((LPSTR)(lpstr2 ? lpstr2 : "null")),
  317. ((LPSTR)(lpstr3 ? lpstr3 : "null"))));
  318. // If we've read any commands or caps from the OEM location we
  319. // skip this...
  320. if (fGotOEMInfo || ( pTG->ModemKeyCreationId != MODEMKEY_FROM_NOTHING) )
  321. {
  322. ERRMSG(("<<WARNING>> Got OEM info: Skipping AWMODEM.INF file search!\r\n"));
  323. }
  324. else
  325. {
  326. if (!SearchInfFile(pTG, "AWOEM.INF", lpstr1, lpstr2, lpstr3, dwKey))
  327. SearchInfFile(pTG, "AWMODEM.INF", lpstr1, lpstr2, lpstr3, dwKey);
  328. }
  329. SaveIDandCMD:
  330. BG_CHK(pTG->TmpSettings.dwGot & fGOTPARM_IDCMD);
  331. ProfileWriteString(dwKey, szModemId, pTG->TmpSettings.szID, FALSE);
  332. ProfileWriteString(dwKey, szModemIdCmd, pTG->TmpSettings.szIDCmd, TRUE);
  333. end:
  334. if (dwKey) ProfileClose(dwKey);
  335. return;
  336. }
  337. // state: 0=ineol 1=insectionhdr 2=in midline 3=got] 4=got\r\n
  338. // inputs: \r\n==0 space/tab=1 2=[ 3=] 4=pritables 5=others
  339. USHORT uNext[5][6] =
  340. {
  341. // crlf sp [ ] asc oth
  342. { 0, 0, 1, 2, 2, 2 }, //in eol
  343. { 0, 1, 2, 3, 1, 2 }, //in sectionhdr
  344. { 0, 2, 2, 2, 2, 2 }, //in ordinary line
  345. { 4, 3, 2, 2, 2, 2 }, //found ]
  346. { 4, 4, 4, 4, 4, 4 } //found closing \r\n
  347. };
  348. #define START 0
  349. #define INHEADER1 1
  350. #define INHEADER2 3
  351. #define FOUND 4
  352. void ToCaps(LPBYTE lpb)
  353. {
  354. // capitalize string
  355. USHORT i;
  356. for(i=0; lpb && lpb[i]; i++)
  357. {
  358. if(lpb[i] >= 'a' && lpb[i] <= 'z')
  359. lpb[i] -= 32;
  360. }
  361. }
  362. BOOL SearchInfFile(PThrdGlbl pTG, LPSTR lpstrFile, LPSTR lpstr1, LPSTR lpstr2, LPSTR lpstr3, DWORD_PTR dwLocalKey)
  363. {
  364. #if defined(DOSIO) || defined(KFIL)
  365. char bTemp[BIGTEMPSIZE];
  366. char szHeader[SMALLTEMPSIZE+SMALLTEMPSIZE];
  367. char bTemp2[SMALLTEMPSIZE+SMALLTEMPSIZE];
  368. UINT uLen, state=0, input=0, uHdrLen;
  369. HFILE hfile;
  370. LPBYTE lpb, lpbCurr;
  371. uLen = GetWindowsDirectory(bTemp, BIGTEMPSIZE-15);
  372. if(!uLen)
  373. {
  374. BG_CHK(FALSE);
  375. return FALSE;
  376. }
  377. // if last char is not a \ then append a '\'
  378. if(bTemp[uLen-1] != '\\')
  379. {
  380. bTemp[uLen++] = '\\';
  381. bTemp[uLen] = 0; // add new 0 terminator
  382. }
  383. _fstrcpy(bTemp+uLen, lpstrFile);
  384. if((hfile = DosOpen(bTemp, 0)) == HFILE_ERROR)
  385. {
  386. ERRMSG(("<<WARNING>> %s: No such file\r\n", (LPSTR)bTemp));
  387. return FALSE;
  388. }
  389. uLen = 0;
  390. lpbCurr = bTemp;
  391. nextround:
  392. faxT2log(("Nextround\r\n", state, input));
  393. state = START;
  394. uHdrLen = 0;
  395. for(;;)
  396. {
  397. if(!uLen)
  398. {
  399. uLen = DosRead( hfile, bTemp, sizeof(bTemp));
  400. if(!uLen || uLen == ((UINT) -1))
  401. goto done;
  402. lpbCurr = bTemp;
  403. }
  404. BG_CHK(state != FOUND);
  405. switch(*lpbCurr)
  406. {
  407. case '\r':
  408. case '\n': input = 0; break;
  409. case ' ':
  410. case '\t': input = 1; break;
  411. case '[': input = 2; break;
  412. case ']': input = 3; break;
  413. default: if(*lpbCurr >= 32 && *lpbCurr < 128)
  414. input = 4;
  415. else
  416. input = 5;
  417. break;
  418. }
  419. faxT2log(("state=%d, char=%c input=%d, hdrlen=%d ulen=%d\r\n",
  420. state, *lpbCurr, input, uHdrLen, uLen));
  421. state = uNext[state][input];
  422. faxT2log(("new state=%d\r\n", state));
  423. if(state == FOUND)
  424. {
  425. if(uHdrLen > 2)
  426. break;
  427. else
  428. goto nextround;
  429. }
  430. if(state == INHEADER1)
  431. {
  432. if(*lpbCurr != '[' && uHdrLen < sizeof(szHeader)-1)
  433. szHeader[uHdrLen++] = *lpbCurr;
  434. }
  435. else if(state != INHEADER2)
  436. uHdrLen=0;
  437. lpbCurr++;
  438. uLen--;
  439. // szHeader[uHdrLen] = 0;
  440. faxT2log(("%d %s\r\n", uHdrLen, (LPSTR)szHeader));
  441. }
  442. faxT2log(("Found[%s]\r\n", (LPSTR)szHeader));
  443. BG_CHK(uHdrLen > 2);
  444. // uHdrLen--; // get rid of trailing ]
  445. szHeader[uHdrLen] = 0;
  446. // capitalize search string
  447. ToCaps(szHeader);
  448. TRACE(("Found[%s]\r\n", (LPSTR)szHeader));
  449. if( (lpstr1 ? my_fstrstr(lpstr1, szHeader) : FALSE) ||
  450. (lpstr2 ? my_fstrstr(lpstr2, szHeader) : FALSE) ||
  451. (lpstr3 ? my_fstrstr(lpstr3, szHeader) : FALSE) )
  452. {
  453. TRACE(("<<WARNING>> Copying INI file section [%s] from %s to %s\r\n",
  454. (LPSTR)szHeader, (LPSTR)lpstrFile, (LPSTR)szIniFile));
  455. DosClose( hfile);
  456. // read the whole section as profile string
  457. if(GetPrivateProfileString(szHeader, NULL, "", bTemp, sizeof(bTemp), lpstrFile) == 0)
  458. {
  459. ERRMSG(("<<ERROR>> Can't read INF file section\r\n"));
  460. return FALSE;
  461. }
  462. // copy it to our IniFile
  463. for(lpb=bTemp; *lpb; lpb += _fstrlen(lpb)+1)
  464. {
  465. // lpb is a key in the [szHeader] section of the INF file
  466. if(GetPrivateProfileString(szHeader, lpb, "", bTemp2, sizeof(bTemp2), lpstrFile) == 0)
  467. {
  468. ERRMSG(("<<ERROR>> Can't read INF file entry\r\n"));
  469. }
  470. else
  471. {
  472. // copy it to our IniFile
  473. ProfileWriteString(dwLocalKey, lpb, bTemp2, FALSE);
  474. (MyDebugPrint(pTG, LOG_ALL, "Wrote %s=%s\r\n", (LPSTR)lpb, (LPSTR)bTemp2));
  475. }
  476. }
  477. // found what we wanted. Outta here
  478. return TRUE;
  479. }
  480. // couldnt match, try again
  481. (MyDebugPrint(pTG, LOG_ALL, "No match\r\n"));
  482. goto nextround;
  483. done:
  484. (MyDebugPrint(pTG, LOG_ALL, "End of INF file %s\r\n", (LPSTR)lpstrFile));
  485. // end of inf file--close it
  486. DosClose(hfile);
  487. #endif // DOSIO || KFIL
  488. return FALSE;
  489. }
  490. void CheckAwmodemInf(PThrdGlbl pTG)
  491. {
  492. #if defined(DOSIO) || defined(KFIL)
  493. USHORT uLen;
  494. char bTemp[BIGTEMPSIZE];
  495. HFILE hfile;
  496. uLen = (USHORT)GetWindowsDirectory(bTemp, sizeof(bTemp)-15);
  497. if(!uLen)
  498. {
  499. BG_CHK(FALSE);
  500. return;
  501. }
  502. // if last char is not a \ then append a '\'
  503. if(bTemp[uLen-1] != '\\')
  504. {
  505. bTemp[uLen++] = '\\';
  506. bTemp[uLen] = 0; // add new 0 terminator
  507. }
  508. _fstrcpy(bTemp+uLen, "AWMODEM.INF");
  509. if((hfile = DosOpen(bTemp, 0)) != HFILE_ERROR)
  510. {
  511. TRACE(("<<WARNING>> %s exists\r\n", (LPSTR)bTemp));
  512. }
  513. else
  514. {
  515. if((hfile = DosCreate(bTemp, 0)) == HFILE_ERROR)
  516. {
  517. ERRMSG(("<<ERROR>> Could not create %s\r\n", (LPSTR)bTemp));
  518. }
  519. else
  520. {
  521. DosWrite( hfile, (LPSTR)szAwmodemInf, sizeof(szAwmodemInf)-1);
  522. DosClose( hfile);
  523. TRACE(("<<WARNING>> Created %s\r\n", (LPSTR)bTemp));
  524. }
  525. }
  526. return;
  527. #endif //DOSIO || KFIL
  528. }
  529. USHORT iModemGetCmdTab(PThrdGlbl pTG, DWORD dwLineID, DWORD dwLineIDType,
  530. LPCMDTAB lpCmdTab, LPMODEMCAPS lpMdmCaps, LPMODEMEXTCAPS lpMdmExtCaps,
  531. BOOL fInstall)
  532. {
  533. USHORT uLen1, uLen2, uRet = INIT_INTERNAL_ERROR;
  534. USHORT uPassCount = 0;
  535. USHORT uInstall=0;
  536. BOOL fDontPurge=FALSE; //If true, we won't delete section in install.
  537. int i;
  538. #ifndef METAPORT
  539. BG_CHK(dwLineIDType == LINEID_COMM_PORTNUM);
  540. #else
  541. BG_CHK( dwLineIDType == LINEID_COMM_PORTNUM
  542. || dwLineIDType == LINEID_COMM_HANDLE);
  543. #endif
  544. if (!imodem_alloc_tmp_strings(pTG)) goto done;
  545. pTG->TmpSettings.lpMdmCaps = lpMdmCaps;
  546. pTG->TmpSettings.lpMdmExtCaps = lpMdmExtCaps;
  547. if(fInstall==fMDMINIT_INSTALL) goto DoInstall;
  548. ReadConfig:
  549. // check for ModemIdCmd, ModemId, ModemFaxClasses,
  550. // ResetCommand, SetupCommand, PreDialCommand, PreAnswerCommand,
  551. // ExitCommand, FaxSerialSpeed vars
  552. // and (if Class1) ModemSendCaps, ModemRecvCaps
  553. // if all present [some exceptions--see below], then verify that
  554. // ModemId is still correct (send ModemIdCmd, get ModemId)
  555. // if correct then copy all INI values into lpMdmCaps and lpCmdTab
  556. // else do full install
  557. // get ModemCaps from current settings
  558. imodem_clear_tmp_settings(pTG);
  559. if (!iModemGetCurrentModemInfo(pTG))
  560. {
  561. goto DoInstall;
  562. }
  563. SmashCapsAccordingToSettings(pTG);
  564. if (! pTG->fCommInitialized) {
  565. if( ! T30ComInit(pTG, pTG->hComm) ) {
  566. (MyDebugPrint(pTG, LOG_ALL, "T30ComInit failed \r\n"));
  567. goto done;
  568. }
  569. FComDTR(pTG, TRUE); // Raise DTR in ModemInit
  570. FComFlush(pTG);
  571. pTG->fCommInitialized = 1;
  572. }
  573. // do modem reset, or ID check won't work (because of echo)
  574. BG_CHK(pTG->TmpSettings.dwGot&fGOTCMD_Reset);
  575. if (!pTG->TmpSettings.szReset[0])
  576. {
  577. ERRMSG(("<<WARNING>> NULL reset command specified!\r\n"));
  578. }
  579. else
  580. {
  581. if(iModemReset(pTG, pTG->TmpSettings.szReset) < 0)
  582. {
  583. fDontPurge=TRUE; // we specifically don't purge in this case.
  584. goto DoInstall;
  585. }
  586. }
  587. // check ID
  588. // a way around this Id check. If IdCmd has been manually deleted, skip chk
  589. BG_CHK(pTG->TmpSettings.szIDCmd && pTG->TmpSettings.szID);
  590. uLen1 = (USHORT)_fstrlen(pTG->TmpSettings.szIDCmd);
  591. if (fInstall==fMDMINIT_ANSWER || !uLen1) {uRet = 0; goto done;}
  592. uLen2 = (USHORT)_fstrlen(pTG->TmpSettings.szID);
  593. BG_CHK(uLen2);
  594. for(i=0; i<3; i++)
  595. {
  596. GetIdResp(pTG, pTG->TmpSettings.szIDCmd, uLen1, pTG->TmpSettings.szResponseBuf,
  597. RESPONSEBUFSIZE);
  598. if(my_fstrstr(pTG->TmpSettings.szResponseBuf, pTG->TmpSettings.szID))
  599. {
  600. TRACE(("<<WARNING>> Modem IDs (%s): (%s\r\n)-->(%s) confirmed\r\n",
  601. (LPSTR)pTG->TmpSettings.szID, (LPSTR)pTG->TmpSettings.szIDCmd,
  602. (LPSTR)pTG->TmpSettings.szResponseBuf));
  603. uRet = 0;
  604. goto done;
  605. }
  606. }
  607. // Failed ID check
  608. // Fall thru to DoInstall;
  609. DoInstall:
  610. if(uPassCount > 0)
  611. {
  612. TRACE(("<<ERROR>> Install looping!!\r\n"));
  613. BG_CHK(FALSE);
  614. uRet = INIT_INTERNAL_ERROR;
  615. goto done;
  616. }
  617. uPassCount++;
  618. // +++ currently we always do a "clean" install -- dwGot=0
  619. // EXCEPT that we use fDontPurge do determine whether we
  620. // delete the profile section or not.
  621. fDontPurge=fDontPurge|| (pTG->TmpSettings.uDontPurge!=0);
  622. imodem_clear_tmp_settings(pTG);
  623. BG_CHK(!pTG->TmpSettings.dwGot);
  624. if(uRet = iModemInstall(pTG, dwLineID, dwLineIDType, fDontPurge))
  625. goto done; // failed
  626. else
  627. goto ReadConfig; // success
  628. // on success we want to go back and start over because (a) we want to check
  629. // that everything is indeed OK and (b) UI etc may have modfied some of the
  630. // settings so we need to go back and read them in again.
  631. done:
  632. if (!uRet)
  633. {
  634. char *pb = pTG->bModemCmds;
  635. UINT u;
  636. // Initialize all command strings in lpCmdTab to static buffer,
  637. // copying from the corresponding strings in the TmpSettings structure.
  638. // the latter strings point into
  639. // the temporarily allocated buffer allocated in
  640. // imodem_alloc_tmp_strings and will be freed on exit.
  641. _fmemset(lpCmdTab, 0, sizeof(CMDTAB));
  642. #define ADDSTRING(STRING) \
  643. BG_CHK(pTG->TmpSettings.STRING); \
  644. u = _fstrlen(pTG->TmpSettings.STRING)+1; \
  645. _fmemcpy(pb, pTG->TmpSettings.STRING,u); \
  646. lpCmdTab->STRING=pb;\
  647. pb+=u; \
  648. BG_CHK(pb<=(pTG->bModemCmds+sizeof(pTG->bModemCmds)));
  649. ADDSTRING(szReset);
  650. ADDSTRING(szSetup);
  651. ADDSTRING(szExit);
  652. ADDSTRING(szPreDial);
  653. ADDSTRING(szPreAnswer);
  654. }
  655. lpCmdTab->dwSerialSpeed = pTG->SerialSpeedInit;
  656. lpCmdTab->dwFlags = pTG->TmpSettings.dwFlags;
  657. imodem_free_tmp_strings(pTG);
  658. return uRet;
  659. }
  660. USHORT iModemInstall(PThrdGlbl pTG, DWORD dwLineID, DWORD dwLineIDType, BOOL fDontPurge)
  661. {
  662. USHORT uRet = 0;
  663. BOOL fGotOEMInfo = FALSE;
  664. DWORD_PTR hkFr;
  665. DWORD localModemKeyCreationId;
  666. CheckAwmodemInf(pTG); // check that AWMODEM.INf exist, otherwise create it
  667. if (!pTG->TmpSettings.dwGot) {
  668. /////// clear settings in input //////
  669. // Clear out persistant (registry) info...
  670. if (!fDontPurge && !ProfileDeleteSection(DEF_BASEKEY,pTG->FComModem.rgchKey))
  671. {
  672. ERRMSG(("<<WARNING>> ClearCurrentModemInfo:Can't delete section %s\r\n",
  673. (LPSTR) pTG->FComModem.rgchKey));
  674. }
  675. // Since the above deletes the entire section, we have to write
  676. // back things that are important to us, which currently
  677. // is the OEM key...
  678. {
  679. DWORD_PTR dwKey;
  680. if (!(dwKey = ProfileOpen(pTG->FComModem.dwProfileID,
  681. pTG->FComModem.rgchKey, fREG_CREATE |fREG_READ|fREG_WRITE))
  682. || !ProfileWriteString(dwKey, szOEMKEY,
  683. pTG->FComModem.rgchOEMKey, FALSE))
  684. {
  685. ERRMSG(("<<WARNING>> Couldn't write OEM Key after clearing section\r\n"));
  686. }
  687. // may be save other things here, like modem params???
  688. if (dwKey) {ProfileClose(dwKey); dwKey=0;}
  689. }
  690. //
  691. // 1. Check to see if this modem is defined in Adaptive.Inf
  692. //
  693. SearchNewInfFile(pTG, pTG->ResponsesKeyName, NULL, FALSE);
  694. if (pTG->fAdaptiveRecordFound) {
  695. if (! pTG->fAdaptiveRecordUnique) {
  696. //
  697. // need to talk to a modem to find out its ID.
  698. //
  699. TalkToModem (pTG, FALSE);
  700. if (pTG->fAdaptiveRecordUnique) {
  701. SearchNewInfFile(pTG, pTG->ResponsesKeyName, NULL, TRUE);
  702. }
  703. else {
  704. pTG->fAdaptiveRecordFound = 0;
  705. pTG->ModemClass = 0;
  706. }
  707. }
  708. }
  709. //
  710. // 2. Save either Adaptive.inf or Unimodem.inf [or nothing] to Registry
  711. //
  712. if (pTG->fAdaptiveRecordFound) {
  713. pTG->ModemKeyCreationId = MODEMKEY_FROM_ADAPTIVE;
  714. SaveInf2Registry(pTG);
  715. }
  716. else {
  717. if ( hkFr = ProfileOpen( OEM_BASEKEY, pTG->lpszUnimodemFaxKey, fREG_READ) ) {
  718. pTG->fUnimodemFaxDefined = 1;
  719. pTG->ModemKeyCreationId = MODEMKEY_FROM_UNIMODEM;
  720. ProfileClose( hkFr);
  721. iModemCopyOEMInfo(pTG);
  722. }
  723. else {
  724. pTG->fUnimodemFaxDefined = 0;
  725. pTG->ModemKeyCreationId = MODEMKEY_FROM_NOTHING;
  726. }
  727. }
  728. localModemKeyCreationId = pTG->ModemKeyCreationId;
  729. pTG->AdaptiveAnswerEnable = 0;
  730. //
  731. // At this point we have all the info from Adaptive.inf or Unimodem Reg.
  732. // into Modem Reg.
  733. // We have nothing in memory.
  734. //
  735. if (! pTG->ModemClass) {
  736. ReadModemClassFromRegistry(pTG);
  737. }
  738. if (! pTG->ModemClass) {
  739. TalkToModem(pTG, TRUE);
  740. SaveModemClass2Registry(pTG);
  741. }
  742. //
  743. // Get data from Modem Reg. into memory
  744. //
  745. iModemGetCurrentModemInfo(pTG);
  746. pTG->ModemKeyCreationId = localModemKeyCreationId;
  747. }
  748. //
  749. // We are ready now to initialize the hardware.
  750. // Can be second init (first one is in TalkToModem
  751. //
  752. if(! T30ComInit(pTG, pTG->hComm) )
  753. {
  754. (MyDebugPrint(pTG, LOG_ERR,"<<ERROR>> Cannot Init COM port\r\n"));
  755. // error already set to ERR_COMM_FAILED
  756. uRet = INIT_PORTBUSY;
  757. goto done;
  758. }
  759. FComDTR(pTG, TRUE); // Raise DTR in ModemInit
  760. FComFlush(pTG);
  761. pTG->fCommInitialized = 1;
  762. // we use this to decide if we must read our OEM inf files or not....
  763. fGotOEMInfo = (pTG->TmpSettings.dwGot & (fGOTCMDS|fGOTCAPS|fGOTPARMS));
  764. ReTry:
  765. // At this point, we have possibly an incompletely and/or
  766. // incorrectly filled out set of commands and capabilities.
  767. // must be first, or modem is in a totally unknown state
  768. if(uRet = iModemFigureOutCmdsExt(pTG))
  769. goto done;
  770. // iModemFigureOut leaves modem is a good (synced up) state
  771. // this needs to be _after_ lpCmdTab is filled out
  772. if(!iModemGetCaps(pTG, pTG->TmpSettings.lpMdmCaps,
  773. pTG->TmpSettings.dwSerialSpeed,
  774. pTG->TmpSettings.szReset,
  775. &pTG->TmpSettings.dwGot))
  776. {
  777. uRet = INIT_GETCAPS_FAIL;
  778. goto done;
  779. }
  780. // we always save settings here because iModemGetWriteIds below
  781. // will need to possibly override our settings so far...
  782. iModemSaveCurrentModemInfo(pTG);
  783. // must be last since it also does the AWMODEM.INF search
  784. iModemGetWriteIds(pTG, fGotOEMInfo);
  785. CleanModemInfStrings(pTG);
  786. imodem_clear_tmp_settings(pTG);
  787. // Now we've done all we can. We've got all the settings, written them to
  788. // the INI file. Call back the UI function here. This will read the
  789. // current settings from INI file, may modify them and returns OK, Cancel
  790. // and Detect. On OK & Cancel, just exit. On Detect loop back to start
  791. // of this function, but this time _skip_ UNIMODEM & do detection ourself
  792. switch(iModemGetUserFeedback(pTG, dwLineID, dwLineIDType))
  793. {
  794. case IDCANCEL:
  795. uRet = INIT_USERCANCEL;
  796. break;
  797. case IDOK:
  798. uRet = 0;
  799. break;
  800. case IDRETRY:
  801. // We allow the user to keep cmds and detect settings, but
  802. // currently we throw away all settings and try a fresh detect.
  803. imodem_clear_tmp_settings(pTG);
  804. fGotOEMInfo=FALSE;
  805. goto ReTry;
  806. }
  807. done:
  808. return uRet;
  809. }
  810. // This function ptr is passed to the FaxSetup UI. It can only be called
  811. // from inside there. It takes an lpCmdTab & lpMdmCaps and verifies them
  812. // as best it can. Expects modem to be all synced up etc.
  813. USHORT TestProc(PThrdGlbl pTG, LPCMDTAB lpCmdTab, LPMODEMCAPS lpMdmCaps, USHORT uClass)
  814. {
  815. USHORT uLen, uSpeed;
  816. if(!lpCmdTab->szReset || !_fstrlen(lpCmdTab->szReset))
  817. {
  818. ERRMSG(("<<ERROR>> NULL RESET string: %s\r\n", (LPSTR)lpCmdTab->szReset));
  819. return T30_BADPARAM;
  820. }
  821. if(iModemReset(pTG, lpCmdTab->szReset) < 0)
  822. {
  823. ERRMSG(("<<ERROR>> Error in RESET string: %s\r\n", (LPSTR)lpCmdTab->szReset));
  824. return T30_MODEMDEAD;
  825. }
  826. if(lpCmdTab->szSetup && (uLen=(USHORT)_fstrlen(lpCmdTab->szSetup)))
  827. {
  828. if(OfflineDialog2(pTG, (LPSTR)lpCmdTab->szSetup, uLen, cbszOK, cbszERROR) != 1)
  829. {
  830. ERRMSG(("<<ERROR>> Error in SETUP string: %s\r\n", (LPSTR)lpCmdTab->szSetup));
  831. return T30_MODEMERROR;
  832. }
  833. }
  834. uSpeed = (USHORT) lpCmdTab->dwSerialSpeed;
  835. if( (uSpeed < 4800) ||
  836. ((uSpeed % 2400) != 0) ||
  837. ((1152 % (uSpeed/100)) != 0) )
  838. {
  839. ERRMSG(("<<ERROR>> Illegal serial speed %ld\r\n", lpCmdTab->dwSerialSpeed));
  840. return T30_BADPARAM;
  841. }
  842. if(!iiModemGoClass(pTG, uClass, lpCmdTab->dwSerialSpeed))
  843. {
  844. ERRMSG(("<<ERROR>> Can't go to class %d at speed %ld\r\n", uClass, lpCmdTab->dwSerialSpeed));
  845. return T30_WRONGTYPE;
  846. }
  847. if(lpCmdTab->szPreDial && (uLen=(USHORT)_fstrlen(lpCmdTab->szPreDial)))
  848. {
  849. if(OfflineDialog2(pTG, (LPSTR)lpCmdTab->szPreDial, uLen, cbszOK, cbszERROR) != 1)
  850. {
  851. ERRMSG(("<<ERROR>> Error in PREDIAL string: %s\r\n", (LPSTR)lpCmdTab->szPreDial));
  852. return T30_MODEMERROR;
  853. }
  854. }
  855. if(lpCmdTab->szPreAnswer && (uLen=(USHORT)_fstrlen(lpCmdTab->szPreAnswer)))
  856. {
  857. if(OfflineDialog2(pTG, (LPSTR)lpCmdTab->szPreAnswer, uLen, cbszOK, cbszERROR) != 1)
  858. {
  859. ERRMSG(("<<ERROR>> Error in PREANSWER string: %s\r\n", (LPSTR)lpCmdTab->szPreAnswer));
  860. return T30_MODEMERROR;
  861. }
  862. }
  863. if(!iiModemGoClass(pTG, 0, 0))
  864. {
  865. ERRMSG(("<<ERROR>> Can't go back to class 0 at speed 2400\r\n"));
  866. return T30_MODEMERROR;
  867. }
  868. // also need to check speeds, but punting on that
  869. return 0;
  870. }
  871. /***-------------------- FLOW CONTROL ----------------------**********
  872. Each modem seems to have it's own way of setting
  873. flow control. Here's a survey
  874. Manuf which modem? Flow Sideeffects
  875. ----- ------------ ---- -----------
  876. Rockwell RC2324AC &K4 &H unused. \Q unused.
  877. US Robotics Sportster14400 &H2 &K0-3 used, &K4 unused. \cmds unused
  878. Courier(HST,V32bis)
  879. PracPeriph PP14400FXMT/SA &K4 &H unsued. \cmds unused.
  880. PP2400EFXSA
  881. Zoom 9600 V.32 VFX &K4 &H unused. \Q unused
  882. UDSMotorola Fastalk \Q1 &H unused &K unused
  883. HayesOptima Optima24/144 &K4 &H unused \cmds unused
  884. MegaHertz P2144 \Q1 \Q4 &H unused &K unused
  885. TwinCom 144/DF &K4 &H unused \Q unused
  886. PCLogic ??? ??? ????
  887. ???? ??? \Q1 &H unused &K unused
  888. ATI 2400 etc &K4 &H unused \cmds unused
  889. MultiTech MultiModemMT1432MU &E5 &H unused &K unused \Q unused
  890. MultiModemII MT932
  891. MultiModemII MT224
  892. Viva 14.4i/Fax and 9624i &K4 &H unused \Q unused &E unused
  893. GVC "9600bps Fax Modem" \Q1 &H unused &K unused &E unused
  894. SmartOne 1442F/1442FX &K4 &H unused \Q unused &E unused
  895. DSI ScoutPlus *F2 &H &E &K \Q1 unused
  896. We had &K4 and \Q1 commands being sent (until 7/10/93).
  897. This is a potential problem for US Robotics, MultiTech
  898. and DSI modems.
  899. US Robotics defaults to ALL flow control disabled
  900. DSI ScoutPlus defaults to CTS/RTS flow control
  901. MultiTech defaults to CTS/RTS flow control
  902. MultiTech is Class2-only, so we may not have trouble there
  903. 7/10/93
  904. Added &H2 command to iModemReInit -- doesn't affect anyone else I think
  905. later
  906. Removed &H2 -- some modems use that as 'help' cmd & display a page
  907. of help info that they refuse to exit except on pressing N or some such!
  908. So we think the modem's hung!
  909. later
  910. Removed *F2 -- Starts a Flassh ROM download on Rockwell!!
  911. ****-------------------- FLOW CONTROL -------------------------*******/
  912. /*************************************************************************
  913. According to "Data and Fax Communications" by Hummel,flow control
  914. settings are as follows
  915. xon both
  916. &H2 &H3 -- US Robotics (though this fatally invokes Help on some modems)
  917. &K4 -- Dallas, Hayes, Practical, Prometheus, Rockwell, Sierra, Telebit
  918. Twincom, Zoom
  919. \Q1 -- AT&T, Dallas, Microcom, Practical, Prometheus, Sierra
  920. *F2 -- Prometheus (though it fatally invokes Flash ROM download on Rockwell)
  921. #K4 -- Sierra-based fax modems
  922. S68=3 -- Telebit
  923. **************************************************************************/
  924. #define AT "AT"
  925. #define ampF "&F"
  926. #define S0_0 "S0=0"
  927. #define E0 "E0"
  928. #define V1 "V1"
  929. #define Q0 "Q0"
  930. #define S7_255 "S7=255"
  931. #define ampD2 "&D2"
  932. #define ampD3 "&D3"
  933. #define bsQ1 "\\Q1"
  934. #define bsJ0 "\\J0"
  935. #define ampK4 "&K4"
  936. #define ampH2 "&H2"
  937. #define ampI2 "&I2"
  938. #define ampE5 "&E5"
  939. #define cr "\r"
  940. //#define ampC1 "&C1"
  941. USHORT iModemFigureOutCmdsExt(PThrdGlbl pTG)
  942. {
  943. USHORT uLen1 = 0, uLen2 = 0;
  944. BOOL fGotFlo;
  945. // At this point, we have possibly an incompletely and/or
  946. // incorrectly filled out set of commands and capabilities.
  947. // Our job here is to use a combination of detection and
  948. // pre-filled commands to come up with a working set of
  949. // commands..
  950. if (pTG->TmpSettings.dwGot & fGOTCMD_Reset)
  951. {
  952. if (!(pTG->TmpSettings.szReset)
  953. || !*(pTG->TmpSettings.szReset)
  954. || iModemReset(pTG, pTG->TmpSettings.szReset) >= 0)
  955. {
  956. goto SkipReset;
  957. }
  958. else
  959. {
  960. ERRMSG(("<<WARNING>> BOGUS supplied reset cmd: \"%s\"\r\n",
  961. (LPSTR) pTG->TmpSettings.szReset));
  962. }
  963. }
  964. // Quick test to see if we have a modem at all...
  965. // +++ REMOVE!
  966. _fstrcpy(pTG->TmpSettings.szSmallTemp1, AT E0 V1 cr);
  967. if(iModemReset(pTG, pTG->TmpSettings.szSmallTemp1) < 0)
  968. {
  969. ERRMSG(("<<ERROR>> can't set ATE0V1\r\n"));
  970. goto modem_dead;
  971. }
  972. _fstrcpy(pTG->TmpSettings.szSmallTemp1, AT ampF S0_0 E0 V1 Q0 cr);
  973. if(iModemReset(pTG, pTG->TmpSettings.szSmallTemp1) >= 0)
  974. goto GotReset;
  975. // too many variants, too slow, V1Q0 are default anyway
  976. //_fstrcpy(pTG->TmpSettings.szSmallTemp1, AT ampF S0_0 E0 V1 cr);
  977. //if(iModemReset(pTG->TmpSettings.szSmallTemp1) >= 0)
  978. // goto GotReset;
  979. _fstrcpy(pTG->TmpSettings.szSmallTemp1, AT ampF S0_0 E0 cr);
  980. if(iModemReset(pTG, pTG->TmpSettings.szSmallTemp1) >= 0)
  981. goto GotReset;
  982. _fstrcpy(pTG->TmpSettings.szSmallTemp1, AT ampF E0 cr);
  983. if(iModemReset(pTG, pTG->TmpSettings.szSmallTemp1) >= 0)
  984. goto GotReset;
  985. ERRMSG(("<<ERROR>> can't set AT&FE0\r\n"));
  986. // Purge comm here, because there may be stuff left in the output
  987. // buffer that FComClose will try to complete, and if the modem
  988. // is dead, that will take a while...
  989. modem_dead:
  990. FComFlush(pTG);
  991. return INIT_MODEMDEAD;
  992. GotReset:
  993. pTG->TmpSettings.dwGot |= fGOTCMD_Reset;
  994. _fstrcpy(pTG->TmpSettings.szReset, pTG->TmpSettings.szSmallTemp1);
  995. SkipReset:
  996. // now try setup cmd
  997. if (pTG->TmpSettings.dwGot & fGOTCMD_Setup)
  998. {
  999. if (!(pTG->TmpSettings.szSetup)
  1000. || !*(pTG->TmpSettings.szSetup)
  1001. || OfflineDialog2(pTG, pTG->TmpSettings.szSetup,
  1002. (USHORT)_fstrlen(pTG->TmpSettings.szSetup), cbszOK,
  1003. cbszERROR)==1)
  1004. {
  1005. goto SkipSetup;
  1006. }
  1007. else
  1008. {
  1009. ERRMSG(("<<WARNING>> BOGUS supplied setup cmd: \"%s\"\r\n",
  1010. (LPSTR) pTG->TmpSettings.szSetup));
  1011. }
  1012. }
  1013. _fstrcpy(pTG->TmpSettings.szSmallTemp1, AT);
  1014. uLen2 = sizeof(AT)-1;
  1015. if(OfflineDialog2(pTG, (LPSTR)(AT S7_255 cr), sizeof(AT S7_255 cr)-1, cbszOK, cbszERROR) == 1)
  1016. {
  1017. _fstrcpy(pTG->TmpSettings.szSmallTemp1+uLen2, S7_255);
  1018. uLen2 += sizeof(S7_255)-1;
  1019. }
  1020. else
  1021. ERRMSG(("<<WARNING>> can't set S7=255\r\n"));
  1022. if(OfflineDialog2(pTG, (LPSTR)(AT ampD3 cr), sizeof(AT ampD3 cr)-1, cbszOK, cbszERROR) == 1)
  1023. {
  1024. _fstrcpy(pTG->TmpSettings.szSmallTemp1+uLen2, ampD3);
  1025. uLen2 += sizeof(ampD3)-1;
  1026. }
  1027. else if(OfflineDialog2(pTG, (LPSTR)(AT ampD2 cr), sizeof(AT ampD2 cr)-1, cbszOK, cbszERROR) == 1)
  1028. {
  1029. _fstrcpy(pTG->TmpSettings.szSmallTemp1+uLen2, ampD2);
  1030. uLen2 += sizeof(ampD2)-1;
  1031. }
  1032. else
  1033. ERRMSG(("<<WARNING>> can't set &D3 or &D2\r\n"));
  1034. fGotFlo=FALSE;
  1035. if(OfflineDialog2(pTG, (LPSTR)(AT ampK4 cr), sizeof(AT ampK4 cr)-1, cbszOK, cbszERROR) == 1)
  1036. {
  1037. _fstrcpy(pTG->TmpSettings.szSmallTemp1+uLen2, ampK4);
  1038. uLen2 += sizeof(ampK4)-1;
  1039. fGotFlo=TRUE;
  1040. }
  1041. // JosephJ 3/10/95: We try \Q1\J0 even if &K4 passed,
  1042. // because many japanese modems return OK to &K4 but in fact
  1043. // use \J0 for xon xoff flow control
  1044. if(OfflineDialog2(pTG, (LPSTR)(AT bsQ1 cr), sizeof(AT bsQ1 cr)-1, cbszOK, cbszERROR) == 1)
  1045. {
  1046. _fstrcpy(pTG->TmpSettings.szSmallTemp1+uLen2, bsQ1);
  1047. uLen2 += sizeof(bsQ1)-1;
  1048. if(OfflineDialog2(pTG, (LPSTR)(AT bsJ0 cr), sizeof(AT bsJ0 cr)-1, cbszOK, cbszERROR) == 1)
  1049. {
  1050. _fstrcpy(pTG->TmpSettings.szSmallTemp1+uLen2, bsJ0);
  1051. uLen2 += sizeof(bsJ0)-1;
  1052. }
  1053. fGotFlo=TRUE;
  1054. }
  1055. if (!fGotFlo)
  1056. {
  1057. ERRMSG(("<<WARNING>> can't set &K4 or \\Q1, trying &K5\r\n"));
  1058. if(OfflineDialog2(pTG, (LPSTR)(AT ampE5 cr), sizeof(AT ampE5 cr)-1, cbszOK, cbszERROR) == 1)
  1059. {
  1060. _fstrcpy(pTG->TmpSettings.szSmallTemp1+uLen2, ampE5);
  1061. uLen2 += sizeof(ampE5)-1;
  1062. fGotFlo=TRUE;
  1063. }
  1064. }
  1065. _fstrcpy(pTG->TmpSettings.szSmallTemp1+uLen2, cr);
  1066. uLen2 += sizeof(cr)-1;
  1067. _fstrcpy(pTG->TmpSettings.szSetup, pTG->TmpSettings.szSmallTemp1);
  1068. pTG->TmpSettings.dwGot |=fGOTCMD_Setup;
  1069. SkipSetup:
  1070. if (!pTG->TmpSettings.dwSerialSpeed)
  1071. {
  1072. pTG->TmpSettings.dwSerialSpeed = pTG->SerialSpeedInit;
  1073. pTG->TmpSettings.dwGot |=fGOTPARM_PORTSPEED;
  1074. }
  1075. return 0;
  1076. }
  1077. void
  1078. TalkToModem (
  1079. PThrdGlbl pTG,
  1080. BOOL fGetClass
  1081. )
  1082. {
  1083. char Command [400];
  1084. char Response[1000];
  1085. DWORD RespLen;
  1086. USHORT uRet;
  1087. char *lpBeg;
  1088. char *lpCur;
  1089. #define uMULTILINE_SAVEENTIRE 0x1234
  1090. //
  1091. // This function implements special case modems firmware identification
  1092. // as well as modem class identification.
  1093. //
  1094. if ( (! fGetClass) && (pTG->AdaptiveCodeId != 1) ) {
  1095. return;
  1096. }
  1097. //
  1098. // Initialize modem
  1099. //
  1100. if(! T30ComInit(pTG, pTG->hComm) ) {
  1101. MyDebugPrint(pTG, LOG_ERR,"ERROR: TalkToModem cannot init COM port\r\n");
  1102. return;
  1103. }
  1104. FComDTR(pTG, TRUE); // Raise DTR in ModemInit
  1105. FComFlush(pTG);
  1106. pTG->fCommInitialized = 1;
  1107. sprintf (Command, "AT E0 Q0 V1\r" );
  1108. if( (uRet = OfflineDialog2(pTG, (LPSTR) Command, (USHORT) strlen(Command), cbszOK, cbszERROR) ) != 1) {
  1109. MyDebugPrint(pTG, LOG_ERR, "TalkToModem 1 %s FAILED\n", Command);
  1110. return;
  1111. }
  1112. MyDebugPrint(pTG, LOG_ALL, "TalkToModem 1 %s rets OK\n", Command);
  1113. if (fGetClass) {
  1114. //
  1115. // Get modem class
  1116. //
  1117. pTG->ModemClass=MODEM_CLASS1; // default
  1118. sprintf (Command, "AT+FCLASS=?\r" );
  1119. if( (uRet = OfflineDialog2(pTG, (LPSTR) Command, (USHORT) strlen(Command), cbszOK, cbszERROR) ) != 1) {
  1120. MyDebugPrint(pTG, LOG_ERR, "TalkToModem 1 %s FAILED\n", Command);
  1121. return;
  1122. }
  1123. MyDebugPrint(pTG, LOG_ALL, "TalkToModem 1 %s returned %s\n", Command, pTG->FComModem.bLastReply);
  1124. if (strchr(pTG->FComModem.bLastReply, '1') ) {
  1125. MyDebugPrint(pTG, LOG_ALL, "Default to Class1");
  1126. }
  1127. else if ( lpBeg = strchr (pTG->FComModem.bLastReply, '2') ) {
  1128. lpBeg++;
  1129. if ( *lpBeg != '.' ) {
  1130. MyDebugPrint(pTG, LOG_ALL, "Default to Class2");
  1131. pTG->ModemClass=MODEM_CLASS2;
  1132. }
  1133. else if ( strchr (lpBeg, '2') ) {
  1134. MyDebugPrint(pTG, LOG_ALL, "Default to Class2");
  1135. pTG->ModemClass=MODEM_CLASS2;
  1136. }
  1137. else {
  1138. MyDebugPrint(pTG, LOG_ALL, "Default to Class2.0");
  1139. pTG->ModemClass=MODEM_CLASS2_0;
  1140. }
  1141. }
  1142. else {
  1143. MyDebugPrint(pTG, LOG_ERR, "Could not get valid Class answer. Default to Class1");
  1144. }
  1145. }
  1146. //
  1147. // If needed, get firmware identification.
  1148. //
  1149. switch (pTG->AdaptiveCodeId) {
  1150. case 1:
  1151. // Sportster 28800-33600 internal/external
  1152. sprintf (Command, "ATI7\r" );
  1153. FComFlushOutput(pTG);
  1154. FComDirectAsyncWrite(pTG, (LPSTR) Command, (USHORT) strlen(Command) );
  1155. if ( ( uRet = iiModemDialog( pTG, 0, 0, 5000, uMULTILINE_SAVEENTIRE,1, TRUE,
  1156. cbszOK,
  1157. cbszERROR,
  1158. (CBPSTR)NULL) ) != 1 ) {
  1159. MyDebugPrint(pTG, LOG_ERR, "TalkToModem 2 %s FAILED\n", Command);
  1160. return;
  1161. }
  1162. MyDebugPrint(pTG, LOG_ALL, "TalkToModem 2 %s rets OK\n", Command);
  1163. RespLen = min(sizeof(Response) - 1, strlen(pTG->FComModem.bEntireReply) );
  1164. memcpy(Response, pTG->FComModem.bEntireReply, RespLen);
  1165. Response[RespLen] = 0;
  1166. ToCaps(Response);
  1167. //
  1168. // if "EPROM DATE" is "10/18/95" then the adaptive answer is broken (Hugh Riley, USR 03/25/97).
  1169. // otherwise enable adaptive answer.
  1170. // If we enabled adaptive answer and firmware is broken then the customer needs to upgrade f/w.
  1171. //
  1172. if ( ! strstr(Response, "10/18/95") ) {
  1173. pTG->fAdaptiveRecordUnique = 1;
  1174. return;
  1175. }
  1176. //
  1177. // found "10/18/95". Lets check if this is an EPROM DATE.
  1178. //
  1179. if ( ! (lpBeg = strstr(Response, "EPROM DATE") ) ) {
  1180. return;
  1181. }
  1182. if ( ! (lpCur = strstr(lpBeg, "10/18/95") ) ) {
  1183. pTG->fAdaptiveRecordUnique = 1;
  1184. return;
  1185. }
  1186. if ( ! strstr(lpCur, "DSP DATE") ) {
  1187. pTG->fAdaptiveRecordUnique = 1;
  1188. return;
  1189. }
  1190. return;
  1191. default:
  1192. return;
  1193. }
  1194. return;
  1195. }
  1196. BOOL iModemGetCurrentModemInfo(PThrdGlbl pTG)
  1197. // Reads as much as it can from the current profile. Returns TRUE
  1198. // IFF it has read enough for a proper init.
  1199. // On failure, zero's out everything.
  1200. // All info is maintained in global TmpSettings;
  1201. {
  1202. USHORT uLen1=0, uLen2=0;
  1203. ULONG_PTR dwKey=0;
  1204. ULONG_PTR dwKeyAdaptiveAnswer=0;
  1205. ULONG_PTR dwKeyAnswer=0;
  1206. BOOL fRet=FALSE;
  1207. LPMODEMCAPS lpMdmCaps = pTG->TmpSettings.lpMdmCaps;
  1208. LPMODEMEXTCAPS lpMdmExtCaps = pTG->TmpSettings.lpMdmExtCaps;
  1209. UINT uTmp;
  1210. ULONG_PTR KeyList[10] = {0};
  1211. char KeyName[200];
  1212. DWORD i;
  1213. char lpTemp[MAXCMDSIZE];
  1214. char szClass[10];
  1215. imodem_clear_tmp_settings(pTG);
  1216. //
  1217. // get T.30 modem Fax key
  1218. //
  1219. if ( ! (dwKey = ProfileOpen(pTG->FComModem.dwProfileID, pTG->FComModem.rgchKey, fREG_READ))) {
  1220. goto end;
  1221. }
  1222. //
  1223. // Lets see what modem Class we will use
  1224. //
  1225. uTmp = ProfileGetInt(dwKey, szFixModemClass, 0, FALSE);
  1226. if (uTmp == 1) {
  1227. pTG->ModemClass = MODEM_CLASS1;
  1228. }
  1229. else if (uTmp == 2) {
  1230. pTG->ModemClass = MODEM_CLASS2;
  1231. }
  1232. else if (uTmp == 20) {
  1233. pTG->ModemClass = MODEM_CLASS2_0;
  1234. }
  1235. if (! pTG->ModemClass) {
  1236. MyDebugPrint(pTG, LOG_ERR, "iModemGetCurrentModemInfo: MODEM CLASS was not defined.\n");
  1237. }
  1238. switch (pTG->ModemClass) {
  1239. case MODEM_CLASS1 :
  1240. sprintf(szClass, "Class1");
  1241. break;
  1242. case MODEM_CLASS2 :
  1243. sprintf(szClass, "Class2");
  1244. break;
  1245. case MODEM_CLASS2_0 :
  1246. sprintf(szClass, "Class2_0");
  1247. break;
  1248. default:
  1249. sprintf(szClass, "Class1");
  1250. }
  1251. //
  1252. // depending on a requested operation, find the appropriate settings
  1253. //
  1254. if (pTG->Operation == T30_RX) {
  1255. KeyList[0] = dwKey;
  1256. sprintf(KeyName, "%s\\%s", pTG->FComModem.rgchKey, szClass);
  1257. KeyList[1] = ProfileOpen(pTG->FComModem.dwProfileID, KeyName, fREG_READ);
  1258. sprintf(KeyName, "%s\\%s\\AdaptiveAnswer", pTG->FComModem.rgchKey, szClass);
  1259. KeyList[2] = ProfileOpen(pTG->FComModem.dwProfileID, KeyName, fREG_READ);
  1260. if (KeyList[2] == 0) {
  1261. pTG->AdaptiveAnswerEnable = 0;
  1262. sprintf(KeyName, "%s\\%s\\Receive", pTG->FComModem.rgchKey, szClass);
  1263. KeyList[2] = ProfileOpen(pTG->FComModem.dwProfileID, KeyName, fREG_READ);
  1264. }
  1265. else {
  1266. dwKeyAdaptiveAnswer = KeyList[2];
  1267. pTG->AdaptiveAnswerEnable = 1;
  1268. }
  1269. KeyList[3] = 0;
  1270. }
  1271. else if (pTG->Operation == T30_TX) {
  1272. KeyList[0] = dwKey;
  1273. sprintf(KeyName, "%s\\%s", pTG->FComModem.rgchKey, szClass);
  1274. KeyList[1] = ProfileOpen(pTG->FComModem.dwProfileID, KeyName, fREG_READ);
  1275. sprintf(KeyName, "%s\\%s\\Send", pTG->FComModem.rgchKey, szClass);
  1276. KeyList[2] = ProfileOpen(pTG->FComModem.dwProfileID, KeyName, fREG_READ);
  1277. KeyList[3] = 0;
  1278. }
  1279. else {
  1280. (MyDebugPrint(pTG, LOG_ERR, "iModemGetCurrentModemInfo: INVALID pTG->Operation=%d \n") );
  1281. goto end;
  1282. }
  1283. if (lpMdmCaps->uClasses = (USHORT)ProfileListGetInt(KeyList, szModemFaxClasses, 0))
  1284. pTG->TmpSettings.dwGot |= fGOTCAP_CLASSES;
  1285. if(lpMdmCaps->uClasses & FAXCLASS1)
  1286. {
  1287. if (lpMdmCaps->uSendSpeeds = (USHORT)ProfileListGetInt(KeyList, szModemSendSpeeds, 0))
  1288. pTG->TmpSettings.dwGot |= fGOTCAP_SENDSPEEDS;
  1289. if (lpMdmCaps->uRecvSpeeds = (USHORT)ProfileListGetInt(KeyList, szModemRecvSpeeds, 0))
  1290. pTG->TmpSettings.dwGot |= fGOTCAP_RECVSPEEDS;
  1291. }
  1292. pTG->ModemKeyCreationId = ProfileGetInt(dwKey, szModemKeyCreationId, 0, FALSE);
  1293. //RSL 10/10/96
  1294. pTG->Inst.ProtParams.fEnableV17Send = ProfileListGetInt(KeyList, szEnableV17Send, 1);
  1295. pTG->Inst.ProtParams.fEnableV17Recv = ProfileListGetInt(KeyList, szEnableV17Recv, 1);
  1296. uTmp = ProfileListGetInt(KeyList, szHighestSendSpeed, 0);
  1297. if (uTmp) {
  1298. pTG->Inst.ProtParams.HighestSendSpeed = (SHORT)uTmp;
  1299. }
  1300. uTmp = ProfileListGetInt(KeyList, szLowestSendSpeed, 0);
  1301. if (uTmp) {
  1302. pTG->Inst.ProtParams.LowestSendSpeed = (SHORT)uTmp;
  1303. }
  1304. // new settings
  1305. uTmp = ProfileListGetInt(KeyList, szSerialSpeedInit, 0);
  1306. if (uTmp) {
  1307. pTG->SerialSpeedInit = (UWORD)uTmp;
  1308. pTG->SerialSpeedInitSet = 1;
  1309. pTG->TmpSettings.dwGot |= fGOTPARM_PORTSPEED;
  1310. }
  1311. uTmp = ProfileListGetInt(KeyList, szSerialSpeedConnect, 0);
  1312. if (uTmp) {
  1313. pTG->SerialSpeedConnect = (UWORD)uTmp;
  1314. pTG->SerialSpeedConnectSet = 1;
  1315. pTG->TmpSettings.dwGot |= fGOTPARM_PORTSPEED;
  1316. }
  1317. uTmp = ProfileListGetInt(KeyList, szHardwareFlowControl, 0);
  1318. if (uTmp) {
  1319. pTG->fEnableHardwareFlowControl = 1;
  1320. }
  1321. (MyDebugPrint(pTG, LOG_ALL, "iModemGetCurrentModemInfo: fEnableV17Send=%d, fEnableV17Recv=%d, HighestSendSpeed=%d, Low=%d EnableAdaptAnswer=%d \n",
  1322. pTG->Inst.ProtParams.fEnableV17Send,
  1323. pTG->Inst.ProtParams.fEnableV17Recv,
  1324. pTG->Inst.ProtParams.HighestSendSpeed,
  1325. pTG->Inst.ProtParams.LowestSendSpeed,
  1326. pTG->AdaptiveAnswerEnable) );
  1327. (MyDebugPrint(pTG, LOG_ALL, "HardwareFlowControl=%d, SerialSpeedInit=%d, SerialSpeedConnect=%d\n",
  1328. pTG->fEnableHardwareFlowControl,
  1329. pTG->SerialSpeedInit,
  1330. pTG->SerialSpeedConnect));
  1331. // get CmdTab. We distinguish been a command being not-specified and null.
  1332. //
  1333. if (imodem_list_get_str(pTG, KeyList, szResetCommand,
  1334. pTG->TmpSettings.szReset, MAXCMDSIZE, TRUE))
  1335. pTG->TmpSettings.dwGot |= fGOTCMD_Reset;
  1336. if (imodem_list_get_str(pTG, KeyList, szSetupCommand,
  1337. pTG->TmpSettings.szSetup, MAXCMDSIZE, TRUE))
  1338. pTG->TmpSettings.dwGot |= fGOTCMD_Setup;
  1339. if (imodem_list_get_str(pTG, KeyList, szPreDialCommand,
  1340. pTG->TmpSettings.szPreDial, MAXCMDSIZE, TRUE))
  1341. pTG->TmpSettings.dwGot |= fGOTCMD_PreDial;
  1342. if (imodem_list_get_str(pTG, KeyList, szPreAnswerCommand,
  1343. pTG->TmpSettings.szPreAnswer, MAXCMDSIZE, TRUE))
  1344. pTG->TmpSettings.dwGot |= fGOTCMD_PreAnswer;
  1345. if (imodem_list_get_str(pTG, KeyList, szExitCommand,
  1346. pTG->TmpSettings.szExit, MAXCMDSIZE, TRUE))
  1347. pTG->TmpSettings.dwGot |= fGOTCMD_PreExit;
  1348. //
  1349. // Adaptive Answer strings ONLY.
  1350. //
  1351. if (pTG->AdaptiveAnswerEnable) {
  1352. pTG->AnswerCommandNum = 0;
  1353. // get Answer commands key
  1354. sprintf(KeyName, "%s\\Class1\\AdaptiveAnswer\\AnswerCommand", pTG->FComModem.rgchKey);
  1355. dwKeyAnswer = ProfileOpen(pTG->FComModem.dwProfileID, KeyName, fREG_READ);
  1356. if (dwKeyAnswer == 0) {
  1357. MyDebugPrint(pTG, LOG_ERR, "iModemGetCurrentModemInfo: AdaptiveAnswer\\AnswerCommand does not exist\n");
  1358. goto lPostAdaptiveAnswer;
  1359. }
  1360. for (i=1; i<=20; i++) {
  1361. sprintf (KeyName, "%d", i);
  1362. if ( ! imodem_get_str(pTG, dwKeyAnswer, KeyName, lpTemp, MAXCMDSIZE, TRUE) ) {
  1363. break;
  1364. }
  1365. pTG->AnswerCommand[pTG->AnswerCommandNum] = MemAlloc( strlen(lpTemp) + 1);
  1366. sprintf ( pTG->AnswerCommand[pTG->AnswerCommandNum], "%s", lpTemp);
  1367. pTG->AnswerCommandNum++;
  1368. }
  1369. if (pTG->AnswerCommandNum == 0) {
  1370. MyDebugPrint(pTG, LOG_ERR, "iModemGetCurrentModemInfo: AdaptiveAnswer\\AnswerCommand Zero values. \n");
  1371. ProfileClose(dwKeyAnswer);
  1372. goto lPostAdaptiveAnswer;
  1373. }
  1374. ProfileClose(dwKeyAnswer);
  1375. if ( imodem_get_str(pTG, dwKeyAdaptiveAnswer, szModemResponseFaxDetect, lpTemp, MAXCMDSIZE, FALSE) ) {
  1376. pTG->ModemResponseFaxDetect = MemAlloc( strlen(lpTemp) + 1);
  1377. sprintf ( pTG->ModemResponseFaxDetect, "%s", lpTemp);
  1378. }
  1379. if ( imodem_get_str(pTG, dwKeyAdaptiveAnswer, szModemResponseDataDetect, lpTemp, MAXCMDSIZE, FALSE) ) {
  1380. pTG->ModemResponseDataDetect = MemAlloc( strlen(lpTemp) + 1);
  1381. sprintf ( pTG->ModemResponseDataDetect, "%s", lpTemp);
  1382. }
  1383. if ( imodem_get_str(pTG, dwKeyAdaptiveAnswer, szSerialSpeedFaxDetect, lpTemp, MAXCMDSIZE, FALSE) ) {
  1384. pTG->SerialSpeedFaxDetect = (UWORD)atoi (lpTemp);
  1385. }
  1386. if ( imodem_get_str(pTG, dwKeyAdaptiveAnswer, szSerialSpeedDataDetect, lpTemp, MAXCMDSIZE, FALSE) ) {
  1387. pTG->SerialSpeedDataDetect = (UWORD)atoi (lpTemp);
  1388. }
  1389. if ( imodem_get_str(pTG, dwKeyAdaptiveAnswer, szHostCommandFaxDetect, lpTemp, MAXCMDSIZE, TRUE) ) {
  1390. pTG->HostCommandFaxDetect = MemAlloc( strlen(lpTemp) + 1);
  1391. sprintf ( pTG->HostCommandFaxDetect, "%s", lpTemp);
  1392. }
  1393. if ( imodem_get_str(pTG, dwKeyAdaptiveAnswer, szHostCommandDataDetect, lpTemp, MAXCMDSIZE, TRUE) ) {
  1394. pTG->HostCommandDataDetect = MemAlloc( strlen(lpTemp) + 1);
  1395. sprintf ( pTG->HostCommandDataDetect, "%s", lpTemp);
  1396. }
  1397. if ( imodem_get_str(pTG, dwKeyAdaptiveAnswer, szModemResponseFaxConnect, lpTemp, MAXCMDSIZE, FALSE) ) {
  1398. pTG->ModemResponseFaxConnect = MemAlloc( strlen(lpTemp) + 1);
  1399. sprintf ( pTG->ModemResponseFaxConnect, "%s", lpTemp);
  1400. }
  1401. if ( imodem_get_str(pTG, dwKeyAdaptiveAnswer, szModemResponseDataConnect, lpTemp, MAXCMDSIZE, FALSE) ) {
  1402. pTG->ModemResponseDataConnect = MemAlloc( strlen(lpTemp) + 1);
  1403. sprintf ( pTG->ModemResponseDataConnect, "%s", lpTemp);
  1404. }
  1405. }
  1406. lPostAdaptiveAnswer:
  1407. pTG->FixSerialSpeed = (UWORD)ProfileListGetInt(KeyList, szFixSerialSpeed, 0);
  1408. if (pTG->FixSerialSpeed) {
  1409. pTG->TmpSettings.dwGot |= fGOTPARM_PORTSPEED;
  1410. pTG->FixSerialSpeedSet = 1;
  1411. }
  1412. //
  1413. // Merge 3 optional different settings for Serial Speed here
  1414. //
  1415. // FixSerialSpeed overrides the others (init/connect)
  1416. if (pTG->FixSerialSpeedSet) {
  1417. pTG->SerialSpeedInit = pTG->FixSerialSpeed;
  1418. pTG->SerialSpeedConnect = pTG->FixSerialSpeed;
  1419. pTG->SerialSpeedInitSet = 1;
  1420. pTG->SerialSpeedConnectSet = 1;
  1421. }
  1422. // if only one of init/connect then the other is same
  1423. if ( pTG->SerialSpeedInitSet && (!pTG->SerialSpeedConnectSet) ) {
  1424. pTG->SerialSpeedConnect = pTG->SerialSpeedInit;
  1425. pTG->SerialSpeedConnectSet = 1;
  1426. }
  1427. else if ( (!pTG->SerialSpeedInitSet) && pTG->SerialSpeedConnectSet ) {
  1428. pTG->SerialSpeedInit = pTG->SerialSpeedConnect;
  1429. pTG->SerialSpeedInitSet = 1;
  1430. }
  1431. // values init/connect are always initialized.
  1432. // Use (init/connect)Set flags to determine whether there were originally set.
  1433. if (! pTG->SerialSpeedInit) {
  1434. pTG->SerialSpeedInit = 19200;
  1435. pTG->SerialSpeedConnect = 19200;
  1436. }
  1437. #ifndef MDDI
  1438. // +++ Expand as necessary:
  1439. if (ProfileListGetInt(KeyList, szCL1_NO_SYNC_IF_CMD, 1))
  1440. {
  1441. pTG->TmpSettings.dwFlags |= fMDMSP_C1_NO_SYNC_IF_CMD;
  1442. }
  1443. if (ProfileListGetInt(KeyList, szANS_GOCLASS_TWICE, 1))
  1444. {
  1445. pTG->TmpSettings.dwFlags |= fMDMSP_ANS_GOCLASS_TWICE; // DEFAULT
  1446. }
  1447. #define szMDMSP_C1_FCS "Cl1FCS" // 0==dunno 1=NO 2=yes-bad
  1448. // specifies whether the modem reports the 2-byteFCS with
  1449. // received HDLC data. (Elliot bugs# 3641, 3668, 3086 report
  1450. // cases of modems sending incorrect FCS bytes).
  1451. // 9/7/95 JosephJ -- changed default from 0 to 2 because Class1 spec
  1452. // says we should NOT rely on the FCS bytes being computed correctly.
  1453. switch(ProfileListGetInt(KeyList, szMDMSP_C1_FCS, 2))
  1454. {
  1455. case 1: pTG->TmpSettings.dwFlags |= fMDMSP_C1_FCS_NO;
  1456. break;
  1457. case 2: pTG->TmpSettings.dwFlags |= fMDMSP_C1_FCS_YES_BAD;
  1458. break;
  1459. }
  1460. pTG->TmpSettings.dwGot |= fGOTFLAGS;
  1461. #endif //!MDDI
  1462. lpMdmExtCaps->dwDialCaps = ProfileListGetInt(KeyList, szDIALCAPS, 0);
  1463. // Retrieve ID command.
  1464. // a way around this Id check. If IdCmd has been manually deleted, skip chk
  1465. if (imodem_list_get_str(pTG, KeyList, szModemIdCmd,
  1466. pTG->TmpSettings.szIDCmd, MAXCMDSIZE, TRUE))
  1467. {
  1468. pTG->TmpSettings.dwGot |= fGOTPARM_IDCMD;
  1469. if (imodem_list_get_str(pTG, KeyList, szModemId,
  1470. pTG->TmpSettings.szID, MAXIDSIZE, FALSE))
  1471. pTG->TmpSettings.dwGot |= fGOTPARM_ID;
  1472. }
  1473. pTG->TmpSettings.uDontPurge= (USHORT)ProfileListGetInt(KeyList, szDONT_PURGE, 0xff);
  1474. //
  1475. // Classes 2 and 2.0
  1476. //
  1477. if (pTG->ModemClass != MODEM_CLASS1) {
  1478. uTmp = ProfileListGetInt(KeyList,szRECV_BOR, 0);
  1479. pTG->CurrentMFRSpec.iReceiveBOR = (USHORT) uTmp;
  1480. uTmp = ProfileListGetInt(KeyList, szSEND_BOR, 0);
  1481. pTG->CurrentMFRSpec.iSendBOR = (USHORT) uTmp;
  1482. uTmp = ProfileListGetInt(KeyList, szSW_BOR, 0);
  1483. pTG->CurrentMFRSpec.fSWFBOR = (BOOL) uTmp;
  1484. uTmp = ProfileListGetInt(KeyList, szDC2CHAR, 82);
  1485. pTG->CurrentMFRSpec.szDC2[0] = (CHAR) uTmp;
  1486. uTmp = ProfileListGetInt(KeyList, szIS_SIERRA, 0);
  1487. pTG->CurrentMFRSpec.bIsSierra = (BOOL) uTmp;
  1488. uTmp = ProfileListGetInt(KeyList, szIS_EXAR, 0);
  1489. pTG->CurrentMFRSpec.bIsExar = (BOOL) uTmp;
  1490. uTmp = ProfileListGetInt(KeyList, szSKIP_CTRL_Q, 0);
  1491. pTG->CurrentMFRSpec.fSkipCtrlQ = (BOOL) uTmp;
  1492. }
  1493. if (dwKey) ProfileClose(dwKey);
  1494. #define fMANDATORY (fGOTCMD_Reset|fGOTCMD_Setup|fGOTCAP_CLASSES)
  1495. #define fCLASS1MANDATORY (fMANDATORY | fGOTCAP_SENDSPEEDS | fGOTCAP_RECVSPEEDS)
  1496. fRet = (lpMdmCaps->uClasses & FAXCLASS1)
  1497. ? ((pTG->TmpSettings.dwGot & fCLASS1MANDATORY) == fCLASS1MANDATORY)
  1498. : ((pTG->TmpSettings.dwGot & fMANDATORY) == fMANDATORY);
  1499. end:
  1500. for (i=1; i<10; i++) {
  1501. if (KeyList[i] != 0) {
  1502. ProfileClose (KeyList[i]);
  1503. }
  1504. }
  1505. return fRet;
  1506. }
  1507. BOOL iModemSaveCurrentModemInfo(PThrdGlbl pTG)
  1508. {
  1509. DWORD_PTR dwKey=0;
  1510. LPMODEMCAPS lpMdmCaps = pTG->TmpSettings.lpMdmCaps;
  1511. char KeyName[200];
  1512. DWORD_PTR dwKeyAdaptiveAnswer=0;
  1513. DWORD_PTR dwKeyAnswer=0;
  1514. DWORD i;
  1515. char szClass[10];
  1516. //
  1517. // BUGBUG: Right now we save all major caps at the root level.
  1518. //
  1519. if (!(dwKey=ProfileOpen(pTG->FComModem.dwProfileID, pTG->FComModem.rgchKey,
  1520. fREG_CREATE | fREG_READ | fREG_WRITE)))
  1521. {
  1522. ERRMSG(("<<ERROR>> Couldn't get location of modem info.\n\r"));
  1523. goto failure;
  1524. }
  1525. if (! pTG->ModemClass) {
  1526. pTG->ModemClass = MODEM_CLASS1;
  1527. MyDebugPrint(pTG, LOG_ERR, "iModemGetCurrentModemInfo: MODEM CLASS was not defined.\n");
  1528. }
  1529. switch (pTG->ModemClass) {
  1530. case MODEM_CLASS1 :
  1531. ProfileWriteString(dwKey, szFixModemClass, "1", TRUE);
  1532. sprintf(szClass, "Class1");
  1533. break;
  1534. case MODEM_CLASS2 :
  1535. sprintf(szClass, "Class2");
  1536. ProfileWriteString(dwKey, szFixModemClass, "2", TRUE);
  1537. break;
  1538. case MODEM_CLASS2_0 :
  1539. sprintf(szClass, "Class2_0");
  1540. ProfileWriteString(dwKey, szFixModemClass, "20", TRUE);
  1541. break;
  1542. default:
  1543. sprintf(szClass, "Class1");
  1544. }
  1545. wsprintf(pTG->TmpSettings.szSmallTemp1, "%lu", (unsigned long) pTG->ModemKeyCreationId );
  1546. ProfileWriteString(dwKey, szModemKeyCreationId, pTG->TmpSettings.szSmallTemp1, FALSE);
  1547. ////// Modem Commands
  1548. ProfileWriteString(dwKey, szResetCommand, pTG->TmpSettings.szReset, TRUE);
  1549. ProfileWriteString(dwKey, szSetupCommand, pTG->TmpSettings.szSetup, TRUE);
  1550. ProfileWriteString(dwKey, szExitCommand , pTG->TmpSettings.szExit, TRUE);
  1551. ProfileWriteString(dwKey, szPreDialCommand , pTG->TmpSettings.szPreDial, TRUE);
  1552. ProfileWriteString(dwKey, szPreAnswerCommand, pTG->TmpSettings.szPreAnswer, TRUE);
  1553. //
  1554. // Adaptive Answer
  1555. //
  1556. if (pTG->AdaptiveAnswerEnable) {
  1557. // create Class key if it doesn't exist
  1558. sprintf(KeyName, "%s\\%s", pTG->FComModem.rgchKey, szClass);
  1559. dwKeyAdaptiveAnswer = ProfileOpen(pTG->FComModem.dwProfileID, KeyName, fREG_CREATE | fREG_READ | fREG_WRITE);
  1560. if (dwKeyAdaptiveAnswer == 0) {
  1561. ERRMSG(("<<ERROR>> iModemSaveCurrentModemInfo couldn't open Class1.\n\r"));
  1562. goto failure;
  1563. }
  1564. ProfileClose(dwKeyAdaptiveAnswer);
  1565. // create Class1\AdaptiveAnswer key if it doesn't exist
  1566. sprintf(KeyName, "%s\\%s\\AdaptiveAnswer", pTG->FComModem.rgchKey, szClass);
  1567. dwKeyAdaptiveAnswer = ProfileOpen(pTG->FComModem.dwProfileID, KeyName, fREG_CREATE | fREG_READ | fREG_WRITE);
  1568. if (dwKeyAdaptiveAnswer == 0) {
  1569. ERRMSG(("<<ERROR>> iModemSaveCurrentModemInfo couldn't open AdaptiveAnswer.\n\r"));
  1570. goto failure;
  1571. }
  1572. // create Class1\AdaptiveAnswer\Answer key if it doesn't exist
  1573. sprintf(KeyName, "%s\\%s\\AdaptiveAnswer\\AnswerCommand", pTG->FComModem.rgchKey, szClass);
  1574. dwKeyAnswer = ProfileOpen(pTG->FComModem.dwProfileID, KeyName, fREG_CREATE | fREG_READ | fREG_WRITE);
  1575. if (dwKeyAnswer == 0) {
  1576. ERRMSG(("<<ERROR>> iModemSaveCurrentModemInfo couldn't open AdaptiveAnswer\\AnswerCommand .\n\r"));
  1577. goto failure;
  1578. }
  1579. for (i=0; i<pTG->AnswerCommandNum; i++) {
  1580. sprintf (KeyName, "%d", i+1);
  1581. ProfileWriteString (dwKeyAnswer, KeyName , pTG->AnswerCommand[i], TRUE );
  1582. }
  1583. ProfileClose(dwKeyAnswer);
  1584. // store the rest of the AdaptiveAnswer values
  1585. if (pTG->ModemResponseFaxDetect)
  1586. ProfileWriteString (dwKeyAdaptiveAnswer, szModemResponseFaxDetect, pTG->ModemResponseFaxDetect, FALSE);
  1587. if (pTG->ModemResponseDataDetect)
  1588. ProfileWriteString (dwKeyAdaptiveAnswer, szModemResponseDataDetect, pTG->ModemResponseDataDetect, FALSE);
  1589. if (pTG->SerialSpeedFaxDetect) {
  1590. sprintf (KeyName, "%d", pTG->SerialSpeedFaxDetect);
  1591. ProfileWriteString (dwKeyAdaptiveAnswer, szSerialSpeedFaxDetect, KeyName, FALSE);
  1592. }
  1593. if (pTG->SerialSpeedDataDetect) {
  1594. sprintf (KeyName, "%d", pTG->SerialSpeedDataDetect);
  1595. ProfileWriteString (dwKeyAdaptiveAnswer, szSerialSpeedDataDetect, KeyName, FALSE);
  1596. }
  1597. if (pTG->HostCommandFaxDetect)
  1598. ProfileWriteString (dwKeyAdaptiveAnswer, szHostCommandFaxDetect, pTG->HostCommandFaxDetect, TRUE);
  1599. if (pTG->HostCommandDataDetect)
  1600. ProfileWriteString (dwKeyAdaptiveAnswer, szHostCommandDataDetect, pTG->HostCommandDataDetect, TRUE);
  1601. if (pTG->ModemResponseFaxConnect)
  1602. ProfileWriteString (dwKeyAdaptiveAnswer, szModemResponseFaxConnect, pTG->ModemResponseFaxConnect, FALSE);
  1603. if (pTG->ModemResponseDataConnect)
  1604. ProfileWriteString (dwKeyAdaptiveAnswer, szModemResponseDataConnect, pTG->ModemResponseDataConnect, FALSE);
  1605. ProfileClose(dwKeyAdaptiveAnswer);
  1606. }
  1607. if (pTG->fEnableHardwareFlowControl) {
  1608. ProfileWriteString (dwKey, szHardwareFlowControl, "1", FALSE);
  1609. }
  1610. //
  1611. // Serial Speed
  1612. //
  1613. if (!pTG->SerialSpeedInitSet) {
  1614. wsprintf(pTG->TmpSettings.szSmallTemp1, "%lu", (unsigned long) pTG->TmpSettings.dwSerialSpeed);
  1615. ProfileWriteString(dwKey, szFixSerialSpeed, pTG->TmpSettings.szSmallTemp1, FALSE);
  1616. }
  1617. else {
  1618. wsprintf(pTG->TmpSettings.szSmallTemp1, "%lu", (unsigned long) pTG->SerialSpeedInit);
  1619. ProfileWriteString(dwKey, szSerialSpeedInit, pTG->TmpSettings.szSmallTemp1, FALSE);
  1620. }
  1621. #ifndef MDDI
  1622. if (pTG->TmpSettings.dwGot & fGOTFLAGS)
  1623. {
  1624. if (pTG->TmpSettings.dwFlags & fMDMSP_C1_NO_SYNC_IF_CMD)
  1625. {
  1626. ProfileWriteString(dwKey, szCL1_NO_SYNC_IF_CMD, "1", FALSE);
  1627. }
  1628. if (!(pTG->TmpSettings.dwFlags & fMDMSP_ANS_GOCLASS_TWICE))
  1629. {
  1630. ProfileWriteString(dwKey, szANS_GOCLASS_TWICE, "0", FALSE);
  1631. }
  1632. }
  1633. #endif //!MDDI
  1634. // uDontPurge==1 => save 1
  1635. // otherwise => save 0
  1636. wsprintf(pTG->TmpSettings.szSmallTemp1, "%lu", (unsigned long) (pTG->TmpSettings.uDontPurge==1)?1:0);
  1637. ProfileWriteString(dwKey, szDONT_PURGE, pTG->TmpSettings.szSmallTemp1, FALSE);
  1638. ///////// Modem Caps...
  1639. // write out Classes, then Speeds
  1640. wsprintf(pTG->TmpSettings.szSmallTemp1, "%u", (unsigned) lpMdmCaps->uClasses);
  1641. ProfileWriteString(dwKey, szModemFaxClasses, pTG->TmpSettings.szSmallTemp1, FALSE);
  1642. //
  1643. // Classes 2 and 2.0
  1644. //
  1645. if (pTG->ModemClass != MODEM_CLASS1) {
  1646. wsprintf(pTG->TmpSettings.szSmallTemp1, "%lu", (unsigned long) pTG->CurrentMFRSpec.iReceiveBOR);
  1647. ProfileWriteString(dwKey, szRECV_BOR, pTG->TmpSettings.szSmallTemp1, FALSE);
  1648. wsprintf(pTG->TmpSettings.szSmallTemp1, "%lu", (unsigned long) pTG->CurrentMFRSpec.iSendBOR);
  1649. ProfileWriteString(dwKey, szSEND_BOR, pTG->TmpSettings.szSmallTemp1, FALSE);
  1650. wsprintf(pTG->TmpSettings.szSmallTemp1, "%lu", (unsigned long) pTG->CurrentMFRSpec.fSWFBOR);
  1651. ProfileWriteString(dwKey, szSW_BOR, pTG->TmpSettings.szSmallTemp1, FALSE);
  1652. ProfileWriteString(dwKey, szDC2CHAR, pTG->CurrentMFRSpec.szDC2, FALSE);
  1653. wsprintf(pTG->TmpSettings.szSmallTemp1, "%lu", (unsigned long) pTG->CurrentMFRSpec.bIsSierra);
  1654. ProfileWriteString(dwKey, szIS_SIERRA, pTG->TmpSettings.szSmallTemp1, FALSE);
  1655. wsprintf(pTG->TmpSettings.szSmallTemp1, "%lu", (unsigned long) pTG->CurrentMFRSpec.bIsExar);
  1656. ProfileWriteString(dwKey, szIS_EXAR, pTG->TmpSettings.szSmallTemp1, FALSE);
  1657. wsprintf(pTG->TmpSettings.szSmallTemp1, "%lu", (unsigned long) pTG->CurrentMFRSpec.fSkipCtrlQ);
  1658. ProfileWriteString(dwKey, szSKIP_CTRL_Q, pTG->TmpSettings.szSmallTemp1, FALSE);
  1659. }
  1660. if(lpMdmCaps->uClasses & FAXCLASS1)
  1661. {
  1662. wsprintf(pTG->TmpSettings.szSmallTemp1, "%u", (unsigned) lpMdmCaps->uSendSpeeds);
  1663. ProfileWriteString(dwKey, szModemSendSpeeds, pTG->TmpSettings.szSmallTemp1, FALSE);
  1664. wsprintf(pTG->TmpSettings.szSmallTemp1, "%u", (unsigned) lpMdmCaps->uRecvSpeeds);
  1665. ProfileWriteString(dwKey, szModemRecvSpeeds, pTG->TmpSettings.szSmallTemp1, FALSE);
  1666. }
  1667. if (dwKey)
  1668. ProfileClose(dwKey);
  1669. return TRUE;
  1670. failure:
  1671. if (dwKey)
  1672. ProfileClose(dwKey);
  1673. return FALSE;
  1674. }
  1675. BOOL ReadModemClassFromRegistry (PThrdGlbl pTG)
  1676. {
  1677. UINT uTmp;
  1678. DWORD_PTR dwKey;
  1679. if ( ! (dwKey = ProfileOpen(pTG->FComModem.dwProfileID, pTG->FComModem.rgchKey, fREG_READ))) {
  1680. return FALSE;
  1681. }
  1682. //
  1683. // Lets see what modem Class we will use
  1684. //
  1685. uTmp = ProfileGetInt(dwKey, szFixModemClass, 0, FALSE);
  1686. if (uTmp == 1) {
  1687. pTG->ModemClass = MODEM_CLASS1;
  1688. }
  1689. else if (uTmp == 2) {
  1690. pTG->ModemClass = MODEM_CLASS2;
  1691. }
  1692. else if (uTmp == 20) {
  1693. pTG->ModemClass = MODEM_CLASS2_0;
  1694. }
  1695. if (dwKey)
  1696. ProfileClose(dwKey);
  1697. return TRUE;
  1698. }
  1699. BOOL SaveModemClass2Registry (PThrdGlbl pTG)
  1700. {
  1701. DWORD_PTR dwKey=0;
  1702. if (!(dwKey=ProfileOpen(pTG->FComModem.dwProfileID, pTG->FComModem.rgchKey,
  1703. fREG_CREATE | fREG_READ | fREG_WRITE)))
  1704. {
  1705. MyDebugPrint(pTG, LOG_ERR, "<<ERROR>> SaveModemClass2Registry: Couldn't get location of modem info.\n\r");
  1706. goto failure;
  1707. }
  1708. switch (pTG->ModemClass) {
  1709. case MODEM_CLASS1 :
  1710. ProfileWriteString(dwKey, szFixModemClass, "1", TRUE);
  1711. break;
  1712. case MODEM_CLASS2 :
  1713. ProfileWriteString(dwKey, szFixModemClass, "2", TRUE);
  1714. break;
  1715. case MODEM_CLASS2_0 :
  1716. ProfileWriteString(dwKey, szFixModemClass, "20", TRUE);
  1717. break;
  1718. default:
  1719. MyDebugPrint(pTG, LOG_ERR, "<<ERROR>> SaveModemClass2Registry: pTG->ModemClass=%d \r", pTG->ModemClass);
  1720. ProfileWriteString(dwKey, szFixModemClass, "1", TRUE);
  1721. }
  1722. if (dwKey)
  1723. ProfileClose(dwKey);
  1724. return TRUE;
  1725. failure:
  1726. return FALSE;
  1727. }
  1728. BOOL SaveInf2Registry (PThrdGlbl pTG)
  1729. {
  1730. DWORD_PTR dwKey=0;
  1731. LPMODEMCAPS lpMdmCaps = pTG->TmpSettings.lpMdmCaps;
  1732. char KeyName[200];
  1733. DWORD_PTR dwKeyAdaptiveAnswer=0;
  1734. DWORD_PTR dwKeyAnswer=0;
  1735. DWORD i;
  1736. char szClass[10];
  1737. if (!(dwKey=ProfileOpen(pTG->FComModem.dwProfileID, pTG->FComModem.rgchKey,
  1738. fREG_CREATE | fREG_READ | fREG_WRITE)))
  1739. {
  1740. ERRMSG(("<<ERROR>> Couldn't get location of modem info.\n\r"));
  1741. goto failure;
  1742. }
  1743. if (! pTG->ModemClass) {
  1744. MyDebugPrint(pTG, LOG_ERR, "iModemGetCurrentModemInfo: MODEM CLASS was not defined.\n");
  1745. }
  1746. switch (pTG->ModemClass) {
  1747. case MODEM_CLASS1 :
  1748. sprintf(szClass, "Class1");
  1749. ProfileWriteString(dwKey, szFixModemClass, "1", TRUE);
  1750. break;
  1751. case MODEM_CLASS2 :
  1752. sprintf(szClass, "Class2");
  1753. ProfileWriteString(dwKey, szFixModemClass, "2", TRUE);
  1754. break;
  1755. case MODEM_CLASS2_0 :
  1756. sprintf(szClass, "Class2_0");
  1757. ProfileWriteString(dwKey, szFixModemClass, "20", TRUE);
  1758. break;
  1759. default:
  1760. sprintf(szClass, "Class1");
  1761. }
  1762. ////// Modem Commands
  1763. if (pTG->TmpSettings.dwGot & fGOTCMD_Reset)
  1764. ProfileWriteString(dwKey, szResetCommand, pTG->TmpSettings.szReset, TRUE);
  1765. if (pTG->TmpSettings.dwGot & fGOTCMD_Setup)
  1766. ProfileWriteString(dwKey, szSetupCommand, pTG->TmpSettings.szSetup, TRUE);
  1767. if (pTG->TmpSettings.dwGot & fGOTCMD_PreExit)
  1768. ProfileWriteString(dwKey, szExitCommand , pTG->TmpSettings.szExit, TRUE);
  1769. if (pTG->TmpSettings.dwGot & fGOTCMD_PreDial)
  1770. ProfileWriteString(dwKey, szPreDialCommand , pTG->TmpSettings.szPreDial, TRUE);
  1771. if (pTG->TmpSettings.dwGot & fGOTCMD_PreAnswer)
  1772. ProfileWriteString(dwKey, szPreAnswerCommand, pTG->TmpSettings.szPreAnswer, TRUE);
  1773. //
  1774. // Adaptive Answer
  1775. //
  1776. if (pTG->AdaptiveAnswerEnable) {
  1777. // create szClass key if it doesn't exist
  1778. sprintf(KeyName, "%s\\%s", pTG->FComModem.rgchKey, szClass);
  1779. dwKeyAdaptiveAnswer = ProfileOpen(pTG->FComModem.dwProfileID, KeyName, fREG_CREATE | fREG_READ | fREG_WRITE);
  1780. if (dwKeyAdaptiveAnswer == 0) {
  1781. ERRMSG(("<<ERROR>> iModemSaveCurrentModemInfo couldn't open szClass.\n\r"));
  1782. goto failure;
  1783. }
  1784. ProfileClose(dwKeyAdaptiveAnswer);
  1785. // create Class\AdaptiveAnswer key if it doesn't exist
  1786. sprintf(KeyName, "%s\\%s\\AdaptiveAnswer", pTG->FComModem.rgchKey, szClass);
  1787. dwKeyAdaptiveAnswer = ProfileOpen(pTG->FComModem.dwProfileID, KeyName, fREG_CREATE | fREG_READ | fREG_WRITE);
  1788. if (dwKeyAdaptiveAnswer == 0) {
  1789. ERRMSG(("<<ERROR>> iModemSaveCurrentModemInfo couldn't open AdaptiveAnswer.\n\r"));
  1790. goto failure;
  1791. }
  1792. // create Class1\AdaptiveAnswer\Answer key if it doesn't exist
  1793. sprintf(KeyName, "%s\\%s\\AdaptiveAnswer\\AnswerCommand", pTG->FComModem.rgchKey ,szClass);
  1794. dwKeyAnswer = ProfileOpen(pTG->FComModem.dwProfileID, KeyName, fREG_CREATE | fREG_READ | fREG_WRITE);
  1795. if (dwKeyAnswer == 0) {
  1796. ERRMSG(("<<ERROR>> iModemSaveCurrentModemInfo couldn't open AdaptiveAnswer\\AnswerCommand .\n\r"));
  1797. goto failure;
  1798. }
  1799. for (i=0; i<pTG->AnswerCommandNum; i++) {
  1800. sprintf (KeyName, "%d", i+1);
  1801. ProfileWriteString (dwKeyAnswer, KeyName , pTG->AnswerCommand[i], TRUE );
  1802. MemFree( pTG->AnswerCommand[i]);
  1803. pTG->AnswerCommand[i] = NULL;
  1804. }
  1805. pTG->AnswerCommandNum = 0;
  1806. ProfileClose(dwKeyAnswer);
  1807. // store the rest of the AdaptiveAnswer values
  1808. if (pTG->ModemResponseFaxDetect) {
  1809. ProfileWriteString (dwKeyAdaptiveAnswer, szModemResponseFaxDetect, pTG->ModemResponseFaxDetect, FALSE);
  1810. MemFree( pTG->ModemResponseFaxDetect );
  1811. pTG->ModemResponseFaxDetect = NULL;
  1812. }
  1813. if (pTG->ModemResponseDataDetect) {
  1814. ProfileWriteString (dwKeyAdaptiveAnswer, szModemResponseDataDetect, pTG->ModemResponseDataDetect, FALSE);
  1815. MemFree (pTG->ModemResponseDataDetect);
  1816. pTG->ModemResponseDataDetect = NULL;
  1817. }
  1818. if (pTG->SerialSpeedFaxDetect) {
  1819. sprintf (KeyName, "%d", pTG->SerialSpeedFaxDetect);
  1820. ProfileWriteString (dwKeyAdaptiveAnswer, szSerialSpeedFaxDetect, KeyName, FALSE);
  1821. }
  1822. if (pTG->SerialSpeedDataDetect) {
  1823. sprintf (KeyName, "%d", pTG->SerialSpeedDataDetect);
  1824. ProfileWriteString (dwKeyAdaptiveAnswer, szSerialSpeedDataDetect, KeyName, FALSE);
  1825. }
  1826. if (pTG->HostCommandFaxDetect) {
  1827. ProfileWriteString (dwKeyAdaptiveAnswer, szHostCommandFaxDetect, pTG->HostCommandFaxDetect, TRUE);
  1828. MemFree( pTG->HostCommandFaxDetect);
  1829. pTG->HostCommandFaxDetect = NULL;
  1830. }
  1831. if (pTG->HostCommandDataDetect) {
  1832. ProfileWriteString (dwKeyAdaptiveAnswer, szHostCommandDataDetect, pTG->HostCommandDataDetect,TRUE);
  1833. MemFree( pTG->HostCommandDataDetect);
  1834. pTG->HostCommandDataDetect = NULL;
  1835. }
  1836. if (pTG->ModemResponseFaxConnect) {
  1837. ProfileWriteString (dwKeyAdaptiveAnswer, szModemResponseFaxConnect, pTG->ModemResponseFaxConnect, FALSE);
  1838. MemFree( pTG->ModemResponseFaxConnect);
  1839. pTG->ModemResponseFaxConnect = NULL;
  1840. }
  1841. if (pTG->ModemResponseDataConnect) {
  1842. ProfileWriteString (dwKeyAdaptiveAnswer, szModemResponseDataConnect, pTG->ModemResponseDataConnect, FALSE);
  1843. MemFree(pTG->ModemResponseDataConnect);
  1844. pTG->ModemResponseDataConnect = NULL;
  1845. }
  1846. ProfileClose(dwKeyAdaptiveAnswer);
  1847. }
  1848. if (pTG->fEnableHardwareFlowControl) {
  1849. ProfileWriteString (dwKey, szHardwareFlowControl, "1", FALSE);
  1850. }
  1851. //
  1852. // Serial Speed
  1853. //
  1854. if (pTG->SerialSpeedInitSet) {
  1855. wsprintf(pTG->TmpSettings.szSmallTemp1, "%lu", (unsigned long) pTG->SerialSpeedInit);
  1856. ProfileWriteString(dwKey, szSerialSpeedInit, pTG->TmpSettings.szSmallTemp1, FALSE);
  1857. }
  1858. //
  1859. // Classes 2 and 2.0
  1860. //
  1861. if (pTG->ModemClass != MODEM_CLASS1) {
  1862. wsprintf(pTG->TmpSettings.szSmallTemp1, "%lu", (unsigned long) pTG->CurrentMFRSpec.iReceiveBOR);
  1863. ProfileWriteString(dwKey, szRECV_BOR, pTG->TmpSettings.szSmallTemp1, FALSE);
  1864. wsprintf(pTG->TmpSettings.szSmallTemp1, "%lu", (unsigned long) pTG->CurrentMFRSpec.iSendBOR);
  1865. ProfileWriteString(dwKey, szSEND_BOR, pTG->TmpSettings.szSmallTemp1, FALSE);
  1866. wsprintf(pTG->TmpSettings.szSmallTemp1, "%lu", (unsigned long) pTG->CurrentMFRSpec.fSWFBOR);
  1867. ProfileWriteString(dwKey, szSW_BOR, pTG->TmpSettings.szSmallTemp1, FALSE);
  1868. ProfileWriteString(dwKey, szDC2CHAR, pTG->CurrentMFRSpec.szDC2, FALSE);
  1869. wsprintf(pTG->TmpSettings.szSmallTemp1, "%lu", (unsigned long) pTG->CurrentMFRSpec.bIsSierra);
  1870. ProfileWriteString(dwKey, szIS_SIERRA, pTG->TmpSettings.szSmallTemp1, FALSE);
  1871. wsprintf(pTG->TmpSettings.szSmallTemp1, "%lu", (unsigned long) pTG->CurrentMFRSpec.bIsExar);
  1872. ProfileWriteString(dwKey, szIS_EXAR, pTG->TmpSettings.szSmallTemp1, FALSE);
  1873. wsprintf(pTG->TmpSettings.szSmallTemp1, "%lu", (unsigned long) pTG->CurrentMFRSpec.fSkipCtrlQ);
  1874. ProfileWriteString(dwKey, szSKIP_CTRL_Q, pTG->TmpSettings.szSmallTemp1, FALSE);
  1875. }
  1876. if (dwKey)
  1877. ProfileClose(dwKey);
  1878. return TRUE;
  1879. failure:
  1880. if (dwKey)
  1881. ProfileClose(dwKey);
  1882. return FALSE;
  1883. }
  1884. UINT iModemGetUserFeedback(PThrdGlbl pTG, DWORD dwLineID, DWORD dwLineIDType)
  1885. {
  1886. #ifndef DEBUG
  1887. return IDOK; // 8/27/94 JosephJ. Terrib wants it out!
  1888. #else // DEBUG
  1889. LPMODEMCAPS lpMdmCaps = pTG->TmpSettings.lpMdmCaps;
  1890. #ifndef WIN32
  1891. return IDOK;
  1892. #else
  1893. # define szAA "\n\nAccept settings anyway?"
  1894. # define szEM "<empty>"
  1895. UINT uLen=0;
  1896. LPSTR lpsz = pTG->TmpSettings.szResponseBuf;
  1897. UINT uRet = IDOK;
  1898. // Hack to disable UI.
  1899. // if (GetPrivateProfileInt("Modem", "DisableModemClassDialog", 1, szIniFile))
  1900. goto end;
  1901. iModemGetCurrentModemInfo(pTG);
  1902. // for now print out everything into a large message box.
  1903. uLen = wsprintf(lpsz, "Port: %u\n", (unsigned) dwLineID);
  1904. uLen += wsprintf(lpsz+uLen,
  1905. "Classes: %u\n", (unsigned) lpMdmCaps->uClasses);
  1906. uLen += wsprintf(lpsz+uLen,
  1907. "Send Speeds: %u\n", (unsigned) lpMdmCaps->uSendSpeeds);
  1908. uLen += wsprintf(lpsz+uLen, "Recv Speeds: %u",
  1909. (unsigned) lpMdmCaps->uRecvSpeeds);
  1910. uLen += wsprintf(lpsz+uLen, "\n\nReset Command: %s\n",
  1911. (LPSTR) ((pTG->TmpSettings.szReset)? pTG->TmpSettings.szReset : szEM));
  1912. uLen += wsprintf(lpsz+uLen, "Setup Command: %s\n",
  1913. (LPSTR) ((pTG->TmpSettings.szSetup)? pTG->TmpSettings.szSetup : szEM));
  1914. uLen += wsprintf(lpsz+uLen, "Pre-dial Command: %s\n",
  1915. (LPSTR) ((pTG->TmpSettings.szPreDial)?
  1916. pTG->TmpSettings.szPreDial : szEM));
  1917. uLen += wsprintf(lpsz+uLen, "Pre-answer Command: %s\n",
  1918. (LPSTR) ((pTG->TmpSettings.szPreAnswer)?
  1919. pTG->TmpSettings.szPreAnswer :szEM));
  1920. uLen += wsprintf(lpsz+uLen, "Exit Command: %s\n",
  1921. (LPSTR) ((pTG->TmpSettings.szExit)? pTG->TmpSettings.szExit : szEM));
  1922. uLen += wsprintf(lpsz+uLen, "Port Speed: %lu\n",
  1923. (unsigned long) pTG->TmpSettings.dwSerialSpeed);
  1924. uLen += wsprintf(lpsz+uLen, "\nDo you accept these settings?\n");
  1925. BG_CHK(uLen<RESPONSEBUFSIZE);
  1926. if (MessageBox(NULL, pTG->TmpSettings.szResponseBuf, "Fake Fax Setup Dialog",
  1927. MB_TASKMODAL|MB_YESNO)==IDYES)
  1928. {
  1929. LPSTR lpszText = "";
  1930. // UINT uRet1;
  1931. if (MessageBox(NULL,
  1932. "Do you want the system to test these settings?",
  1933. "Fake Fax Setup Dialog",
  1934. MB_TASKMODAL|MB_YESNO)==IDYES)
  1935. {
  1936. USHORT uClass=0;
  1937. if (lpMdmCaps->uClasses & FAXCLASS1) uClass=FAXCLASS1;
  1938. else if (lpMdmCaps->uClasses & FAXCLASS2) uClass=FAXCLASS2;
  1939. else if (lpMdmCaps->uClasses & FAXCLASS2_0) uClass=FAXCLASS2_0;
  1940. #if 0
  1941. switch(uRet1=TestProc(pTG, lpCmdTab, lpMdmCaps, uClass))
  1942. {
  1943. case T30_BADPARAM:
  1944. lpszText = "Test failed: bad parameter." szAA;
  1945. break;
  1946. case T30_MODEMDEAD:
  1947. lpszText = "Test failed: modem not responding." szAA;
  1948. break;
  1949. case T30_MODEMERROR:
  1950. lpszText = "Test failed: modem reports error." szAA;
  1951. break;
  1952. case T30_WRONGTYPE:
  1953. lpszText = "Test failed: wrong class specified." szAA;
  1954. break;
  1955. case T30_OK:
  1956. lpszText = "Test passed.";
  1957. break;
  1958. default:
  1959. lpszText = "Internal error.";
  1960. BG_CHK(FALSE);
  1961. }
  1962. if (uRet1 != T30_OK)
  1963. {
  1964. if (MessageBox(NULL,
  1965. lpszText,
  1966. "Fake Fax Setup Dialog",
  1967. MB_TASKMODAL|MB_YESNO|MB_ICONSTOP)==IDNO)
  1968. {uRet=IDCANCEL;}
  1969. }
  1970. else
  1971. {
  1972. MessageBox(NULL,
  1973. lpszText,
  1974. "Fake Fax Setup Dialog",
  1975. MB_TASKMODAL|MB_OK);
  1976. }
  1977. #endif
  1978. }
  1979. }
  1980. else
  1981. {
  1982. if (MessageBox(NULL,
  1983. "Do you want the system to detect the modem settings?",
  1984. "Fake Fax Setup Dialog",
  1985. MB_TASKMODAL|MB_YESNO)==IDYES)
  1986. {uRet = IDRETRY;}
  1987. else
  1988. {uRet = IDCANCEL;}
  1989. }
  1990. end:
  1991. return uRet;
  1992. #endif // WIN32
  1993. #endif // DEBUG
  1994. }
  1995. BOOL imodem_alloc_tmp_strings(PThrdGlbl pTG)
  1996. {
  1997. WORD w;
  1998. LPSTR lpstr;
  1999. LPVOID lpv;
  2000. BG_CHK( !pTG->TmpSettings.hglb
  2001. && !pTG->TmpSettings.szReset
  2002. && !pTG->TmpSettings.szSetup
  2003. && !pTG->TmpSettings.szExit
  2004. && !pTG->TmpSettings.szPreDial
  2005. && !pTG->TmpSettings.szPreAnswer
  2006. && !pTG->TmpSettings.szID
  2007. && !pTG->TmpSettings.szIDCmd
  2008. && !pTG->TmpSettings.szSmallTemp1
  2009. && !pTG->TmpSettings.szSmallTemp2
  2010. && !pTG->TmpSettings.szResponseBuf);
  2011. w = TMPSTRINGBUFSIZE;
  2012. pTG->TmpSettings.hglb = (ULONG_PTR) MemAlloc(TMPSTRINGBUFSIZE);
  2013. if (!pTG->TmpSettings.hglb) goto failure;
  2014. lpv = (LPVOID) (pTG->TmpSettings.hglb);
  2015. lpstr=(LPSTR)lpv;
  2016. if (!lpstr) {MemFree( (PVOID) pTG->TmpSettings.hglb); pTG->TmpSettings.hglb=0; goto failure;}
  2017. pTG->TmpSettings.lpbBuf = (LPBYTE)lpstr;
  2018. _fmemset(lpstr, 0, TMPSTRINGBUFSIZE);
  2019. pTG->TmpSettings.szReset = lpstr; lpstr+=MAXCMDSIZE;
  2020. pTG->TmpSettings.szSetup = lpstr; lpstr+=MAXCMDSIZE;
  2021. pTG->TmpSettings.szExit = lpstr; lpstr+=MAXCMDSIZE;
  2022. pTG->TmpSettings.szPreDial = lpstr; lpstr+=MAXCMDSIZE;
  2023. pTG->TmpSettings.szPreAnswer = lpstr; lpstr+=MAXCMDSIZE;
  2024. pTG->TmpSettings.szIDCmd = lpstr; lpstr+=MAXCMDSIZE;
  2025. pTG->TmpSettings.szID = lpstr; lpstr+=MAXIDSIZE;
  2026. pTG->TmpSettings.szResponseBuf = lpstr; lpstr+=RESPONSEBUFSIZE;
  2027. pTG->TmpSettings.szSmallTemp1 = lpstr; lpstr+=SMALLTEMPSIZE;
  2028. pTG->TmpSettings.szSmallTemp2 = lpstr; lpstr+=SMALLTEMPSIZE;
  2029. pTG->TmpSettings.dwGot=0;
  2030. if ( ((LPSTR)lpv+TMPSTRINGBUFSIZE) < lpstr)
  2031. {
  2032. BG_CHK(FALSE); goto failure;
  2033. }
  2034. return TRUE;
  2035. failure:
  2036. ERRMSG(("<<ERROR>> init_tmp_strings: MyAlloc/MyLock failed!\r\n"));
  2037. BG_CHK(FALSE);
  2038. return FALSE;
  2039. }
  2040. void imodem_free_tmp_strings(PThrdGlbl pTG)
  2041. {
  2042. if (pTG->TmpSettings.hglb)
  2043. {
  2044. MemFree( (PVOID) pTG->TmpSettings.hglb);
  2045. }
  2046. _fmemset(&pTG->TmpSettings, 0, sizeof(pTG->TmpSettings));
  2047. }
  2048. void imodem_clear_tmp_settings(PThrdGlbl pTG)
  2049. {
  2050. BG_CHK(pTG->TmpSettings.lpMdmCaps);
  2051. _fmemset(pTG->TmpSettings.lpMdmCaps, 0, sizeof(MODEMCAPS));
  2052. _fmemset(pTG->TmpSettings.lpMdmExtCaps, 0, sizeof(MODEMEXTCAPS));
  2053. pTG->TmpSettings.dwGot=0;
  2054. pTG->TmpSettings.uDontPurge=0;
  2055. pTG->TmpSettings.dwSerialSpeed=0;
  2056. pTG->TmpSettings.dwFlags=0;
  2057. _fmemset(pTG->TmpSettings.lpbBuf, 0, TMPSTRINGBUFSIZE);
  2058. }
  2059. BOOL
  2060. imodem_list_get_str(
  2061. PThrdGlbl pTG,
  2062. ULONG_PTR KeyList[10],
  2063. LPSTR lpszName,
  2064. LPSTR lpszCmdBuf,
  2065. UINT cbMax,
  2066. BOOL fCmd)
  2067. {
  2068. int i;
  2069. int Num=0;
  2070. BOOL bRet=0;
  2071. for (i=0; i<10; i++) {
  2072. if (KeyList[i] == 0) {
  2073. Num = i-1;
  2074. break;
  2075. }
  2076. }
  2077. for (i=Num; i>=0; i--) {
  2078. if ( bRet = imodem_get_str(pTG, KeyList[i], lpszName, lpszCmdBuf, cbMax, fCmd) ) {
  2079. return bRet;
  2080. }
  2081. }
  2082. return bRet;
  2083. }
  2084. BOOL imodem_get_str(PThrdGlbl pTG, ULONG_PTR dwKey, LPSTR lpszName, LPSTR lpszCmdBuf, UINT cbMax,
  2085. BOOL fCmd)
  2086. {
  2087. UINT uLen2;
  2088. char *pc = "bogus";
  2089. BG_CHK(cbMax>1);
  2090. *lpszCmdBuf=0;
  2091. uLen2 = ProfileGetString(dwKey, lpszName,
  2092. pc, lpszCmdBuf, cbMax-1);
  2093. if (uLen2)
  2094. {
  2095. if (!_fstrcmp(lpszCmdBuf, pc))
  2096. {
  2097. *lpszCmdBuf=0; return FALSE;
  2098. }
  2099. if (fCmd) EndWithCR(lpszCmdBuf, (USHORT)uLen2);
  2100. }
  2101. return TRUE;
  2102. }
  2103. BOOL iModemCopyOEMInfo(PThrdGlbl pTG)
  2104. {
  2105. return ProfileCopyTree(DEF_BASEKEY, pTG->FComModem.rgchKey, OEM_BASEKEY,
  2106. pTG->lpszUnimodemFaxKey);
  2107. }
  2108. #define MASKOFFV17 0x03
  2109. #define V27_2400MASK 0x00
  2110. #define V27MASK 0x02
  2111. #define V27_V29MASK 0x03
  2112. void SmashCapsAccordingToSettings(PThrdGlbl pTG)
  2113. {
  2114. // INI file has already been read.
  2115. // If !fV17Enable then smash the V17 bits of the Capabilities
  2116. if(!pTG->Inst.ProtParams.fEnableV17Send) pTG->FComModem.CurrMdmCaps.uSendSpeeds &= MASKOFFV17;
  2117. if(!pTG->Inst.ProtParams.fEnableV17Recv) pTG->FComModem.CurrMdmCaps.uRecvSpeeds &= MASKOFFV17;
  2118. //
  2119. // commented out RSL. We run at 19200. Nowhere in awmodem.inf have I seen FixSerialSpeed clause.
  2120. //
  2121. #if 0
  2122. // Adjust RecvSpeeds Caps according to INI setting
  2123. // of DTE baud rate.
  2124. switch(pTG->Inst.FixSerialSpeed)
  2125. {
  2126. case 0: break; // do nothing
  2127. case 4800: pTG->FComModem.CurrMdmCaps.uRecvSpeeds &= V27_2400MASK; // leaves only 2400
  2128. break;
  2129. case 7200: pTG->FComModem.CurrMdmCaps.uRecvSpeeds &= V27MASK; // leaves V27 48 & 24
  2130. break;
  2131. case 9600: pTG->FComModem.CurrMdmCaps.uRecvSpeeds &= V27MASK;
  2132. break;
  2133. case 14400: pTG->FComModem.CurrMdmCaps.uRecvSpeeds &= V27_V29MASK;
  2134. break;
  2135. default: BG_CHK(FALSE);
  2136. }
  2137. #endif
  2138. (MyDebugPrint(pTG, LOG_ALL, "SmashCapsAccordingToSettings: uSendSpeeds=%x uRecvSpeeds=%x \n",
  2139. pTG->FComModem.CurrMdmCaps.uSendSpeeds, pTG->FComModem.CurrMdmCaps.uRecvSpeeds) );
  2140. }
  2141. int
  2142. SearchNewInfFile(
  2143. PThrdGlbl pTG,
  2144. char *Key1,
  2145. char *Key2,
  2146. BOOL fRead
  2147. )
  2148. {
  2149. char szInfSection[] = "SecondKey=";
  2150. DWORD lenNewInf;
  2151. int RetCode = FALSE;
  2152. char Buffer[400]; // to hold lpToken=lpValue string
  2153. char *lpCurrent;
  2154. char *lpStartSection;
  2155. char *lpTmp;
  2156. char *lpToken;
  2157. char *lpValue;
  2158. ToCaps(Key1);
  2159. if (Key2) {
  2160. ToCaps(Key2);
  2161. }
  2162. pTG->AnswerCommandNum = 0;
  2163. if ( ( lenNewInf = strlen(szAdaptiveInf) ) == 0 ) {
  2164. return FALSE;
  2165. }
  2166. //
  2167. // Loop thru all segments.
  2168. // Each segment starts with InfPath=
  2169. //
  2170. lpCurrent = szAdaptiveInf;
  2171. do {
  2172. // find InfPath
  2173. lpStartSection = strstr (lpCurrent, szResponsesKeyName);
  2174. if (! lpStartSection) {
  2175. goto exit;
  2176. }
  2177. lpTmp = strchr (lpStartSection, '\r' );
  2178. if (!lpTmp) {
  2179. goto exit;
  2180. }
  2181. // compare Key1
  2182. if ( strlen(Key1) != (lpTmp - lpStartSection - strlen(szResponsesKeyName) ) ) {
  2183. lpCurrent = lpTmp;
  2184. continue;
  2185. }
  2186. if ( memcmp (lpStartSection+strlen(szResponsesKeyName),
  2187. Key1,
  2188. (ULONG)(lpTmp - lpStartSection - strlen(szResponsesKeyName) ) ) != 0 ) {
  2189. lpCurrent = lpTmp;
  2190. continue;
  2191. }
  2192. // find InfSection
  2193. lpCurrent = lpTmp;
  2194. if (Key2) {
  2195. lpStartSection = strstr (lpCurrent, szInfSection);
  2196. if (! lpStartSection) {
  2197. goto exit;
  2198. }
  2199. lpTmp = strchr (lpStartSection, '\r' );
  2200. if (!lpTmp) {
  2201. goto exit;
  2202. }
  2203. // compare Key2
  2204. if ( strlen(Key2) != (lpTmp - lpStartSection - strlen(szInfSection) ) ) {
  2205. lpCurrent = lpTmp;
  2206. continue;
  2207. }
  2208. if ( memcmp (lpStartSection+strlen(szInfSection),
  2209. Key2,
  2210. (ULONG)(lpTmp - lpStartSection - strlen(szInfSection)) ) != 0 ) {
  2211. lpCurrent = lpTmp;
  2212. continue;
  2213. }
  2214. lpCurrent = lpTmp;
  2215. }
  2216. //
  2217. // both keys matched. Go get settings and return
  2218. //
  2219. do {
  2220. lpCurrent = strchr (lpCurrent, '\r' );
  2221. if (!lpCurrent) {
  2222. goto exit;
  2223. }
  2224. lpCurrent += 2;
  2225. // find next setting inside the matching section
  2226. lpToken = lpCurrent;
  2227. lpCurrent = strchr (lpCurrent, '=' );
  2228. if (!lpCurrent) {
  2229. goto exit;
  2230. }
  2231. lpTmp = strchr (lpToken, '\r' );
  2232. if (!lpTmp) {
  2233. goto exit;
  2234. }
  2235. if (lpCurrent > lpTmp) {
  2236. // empty string
  2237. lpCurrent = lpTmp;
  2238. continue;
  2239. }
  2240. lpValue = ++lpCurrent;
  2241. lpTmp = strchr (lpValue, '\r' );
  2242. if (!lpTmp) {
  2243. goto exit;
  2244. }
  2245. // we parsed the string. Now get it to the Buffer
  2246. if (lpTmp - lpToken > sizeof (Buffer) ) {
  2247. goto exit;
  2248. }
  2249. memcpy(Buffer, lpToken, (ULONG)(lpTmp - lpToken));
  2250. Buffer[lpValue -lpToken - 1] = 0;
  2251. Buffer[lpTmp - lpToken] = 0;
  2252. lpValue = &Buffer[lpValue - lpToken];
  2253. lpToken = Buffer;
  2254. pTG->fAdaptiveRecordFound = 1;
  2255. if ( my_strcmp(lpToken, szAdaptiveAnswerEnable) ) {
  2256. pTG->AdaptiveAnswerEnable = atoi (lpValue);
  2257. }
  2258. else if ( my_strcmp(lpToken, szAdaptiveRecordUnique) ) {
  2259. pTG->fAdaptiveRecordUnique = atoi (lpValue);
  2260. }
  2261. else if ( my_strcmp(lpToken, szAdaptiveCodeId) ) {
  2262. pTG->AdaptiveCodeId = atoi (lpValue);
  2263. if ( ! fRead ) {
  2264. goto exit;
  2265. }
  2266. }
  2267. else if ( my_strcmp(lpToken, szFaxClass) ) {
  2268. ;
  2269. }
  2270. else if ( my_strcmp(lpToken, szHardwareFlowControl) ) {
  2271. pTG->fEnableHardwareFlowControl = atoi (lpValue);
  2272. }
  2273. else if ( my_strcmp(lpToken, szSerialSpeedInit) ) {
  2274. pTG->SerialSpeedInit = (USHORT)atoi (lpValue);
  2275. pTG->SerialSpeedInitSet = 1;
  2276. }
  2277. else if ( my_strcmp(lpToken, szResetCommand) ) {
  2278. sprintf ( pTG->TmpSettings.szReset, "%s\r", lpValue);
  2279. pTG->TmpSettings.dwGot |= fGOTCMD_Reset;
  2280. }
  2281. else if ( my_strcmp(lpToken, szSetupCommand) ) {
  2282. sprintf ( pTG->TmpSettings.szSetup, "%s\r", lpValue);
  2283. pTG->TmpSettings.dwGot |= fGOTCMD_Setup;
  2284. }
  2285. else if ( my_strcmp(lpToken, szAnswerCommand) ) {
  2286. if (pTG->AnswerCommandNum > 20) {
  2287. goto exit;
  2288. }
  2289. pTG->AnswerCommand[pTG->AnswerCommandNum] = MemAlloc( strlen(lpValue) + 1);
  2290. sprintf ( pTG->AnswerCommand[pTG->AnswerCommandNum], "%s", lpValue);
  2291. pTG->AnswerCommandNum++;
  2292. }
  2293. else if ( my_strcmp(lpToken, szModemResponseFaxDetect) ) {
  2294. pTG->ModemResponseFaxDetect = MemAlloc( strlen(lpValue) + 1);
  2295. sprintf ( pTG->ModemResponseFaxDetect, "%s", lpValue);
  2296. }
  2297. else if ( my_strcmp(lpToken, szModemResponseDataDetect) ) {
  2298. pTG->ModemResponseDataDetect = MemAlloc( strlen(lpValue) + 1);
  2299. sprintf ( pTG->ModemResponseDataDetect, "%s", lpValue);
  2300. }
  2301. else if ( my_strcmp(lpToken, szSerialSpeedFaxDetect) ) {
  2302. pTG->SerialSpeedFaxDetect = (USHORT)atoi (lpValue);
  2303. }
  2304. else if ( my_strcmp(lpToken, szSerialSpeedDataDetect) ) {
  2305. pTG->SerialSpeedDataDetect = (USHORT)atoi (lpValue);
  2306. }
  2307. else if ( my_strcmp(lpToken, szHostCommandFaxDetect) ) {
  2308. pTG->HostCommandFaxDetect = MemAlloc( strlen(lpValue) + 1);
  2309. sprintf ( pTG->HostCommandFaxDetect, "%s", lpValue);
  2310. }
  2311. else if ( my_strcmp(lpToken, szHostCommandDataDetect) ) {
  2312. pTG->HostCommandDataDetect = MemAlloc( strlen(lpValue) + 1);
  2313. sprintf ( pTG->HostCommandDataDetect, "%s", lpValue);
  2314. }
  2315. else if ( my_strcmp(lpToken, szModemResponseFaxConnect) ) {
  2316. pTG->ModemResponseFaxConnect = MemAlloc( strlen(lpValue) + 1);
  2317. sprintf ( pTG->ModemResponseFaxConnect, "%s", lpValue);
  2318. }
  2319. else if ( my_strcmp(lpToken, szModemResponseDataConnect) ) {
  2320. pTG->ModemResponseDataConnect = MemAlloc( strlen(lpValue) + 1);
  2321. sprintf ( pTG->ModemResponseDataConnect, "%s", lpValue);
  2322. }
  2323. else if ( my_strcmp(lpToken, szResponsesKeyName2) ) {
  2324. RetCode = TRUE;
  2325. goto exit;
  2326. }
  2327. } while ( 1 ); // section loop
  2328. } while ( 1 ); // file loop
  2329. return (FALSE);
  2330. exit:
  2331. return (RetCode);
  2332. }
  2333. VOID
  2334. CleanModemInfStrings (
  2335. PThrdGlbl pTG
  2336. )
  2337. {
  2338. DWORD i;
  2339. for (i=0; i<pTG->AnswerCommandNum; i++) {
  2340. if (pTG->AnswerCommand[i]) {
  2341. MemFree( pTG->AnswerCommand[i]);
  2342. pTG->AnswerCommand[i] = NULL;
  2343. }
  2344. }
  2345. pTG->AnswerCommandNum = 0;
  2346. if (pTG->ModemResponseFaxDetect) {
  2347. MemFree( pTG->ModemResponseFaxDetect );
  2348. pTG->ModemResponseFaxDetect = NULL;
  2349. }
  2350. if (pTG->ModemResponseDataDetect) {
  2351. MemFree (pTG->ModemResponseDataDetect);
  2352. pTG->ModemResponseDataDetect = NULL;
  2353. }
  2354. if (pTG->HostCommandFaxDetect) {
  2355. MemFree( pTG->HostCommandFaxDetect);
  2356. pTG->HostCommandFaxDetect = NULL;
  2357. }
  2358. if (pTG->HostCommandDataDetect) {
  2359. MemFree( pTG->HostCommandDataDetect);
  2360. pTG->HostCommandDataDetect = NULL;
  2361. }
  2362. if (pTG->ModemResponseFaxConnect) {
  2363. MemFree( pTG->ModemResponseFaxConnect);
  2364. pTG->ModemResponseFaxConnect = NULL;
  2365. }
  2366. if (pTG->ModemResponseDataConnect) {
  2367. MemFree(pTG->ModemResponseDataConnect);
  2368. pTG->ModemResponseDataConnect = NULL;
  2369. }
  2370. }