Leaked source code of windows server 2003
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.

2027 lines
50 KiB

  1. //****************************************************************************
  2. // *
  3. // Microsoft NT Remote Access Service
  4. //
  5. // Copyright (C) 1992-93 Microsft Corporation. All rights reserved.
  6. //
  7. // Filename: mxsutils.c
  8. //
  9. // Revision History
  10. //
  11. // Jun 10, 1992 J. Perry Hannah Created
  12. //
  13. //
  14. // Description: This file contains utility functions used by RASMXS.DLL.
  15. //
  16. //****************************************************************************
  17. #include <nt.h> //These first five headers are used by media.h
  18. #include <ntrtl.h> //The first three(?) are used by DbgUserBreakPoint
  19. #include <nturtl.h>
  20. #include <windows.h>
  21. #include <wanpub.h>
  22. #include <asyncpub.h>
  23. #include <string.h>
  24. #include <malloc.h>
  25. #include <stdlib.h>
  26. #include <stdio.h>
  27. #include <rasman.h>
  28. #include <raserror.h>
  29. #include <rasfile.h>
  30. #include <media.h>
  31. #include <serial.h>
  32. #include <mprlog.h>
  33. #include <rtutils.h>
  34. #include <rasmxs.h>
  35. #include <mxsint.h>
  36. #include <mxspriv.h>
  37. #include "mxswrap.h" // inf file wrapper
  38. #define STRSAFE_NO_DEPRECATE
  39. #include <strsafe.h>
  40. //* Global Variables *******************************************************
  41. //
  42. extern RESPSECTION ResponseSection ; //Shared response section
  43. extern DEVICE_CB *pDeviceList; //Points to DCB linked list
  44. extern HANDLE *pDeviceListMutex ; //Mutex for above list
  45. extern PortGetInfo_t PortGetInfo; //API typedef defined in media.h
  46. extern PortSetInfo_t PortSetInfo; //API typedef defined in media.h
  47. extern BOOL gbLogDeviceDialog; //Indicates logging is on if TRUE
  48. extern HANDLE ghLogFile; //Handle of device log file
  49. extern SavedSections *gpSavedSections ; // Pointer to cached sections
  50. #define NUM_INTERNAL_MACROS 21
  51. TCHAR *gszInternalMacroNames[] =
  52. {
  53. MXS_CARRIERBPS_KEY,
  54. MXS_CONNECTBPS_KEY,
  55. MXS_MESSAGE_KEY,
  56. MXS_PHONENUMBER_KEY,
  57. MXS_DIAGNOSTICS_KEY,
  58. MXS_FACILITIES_KEY,
  59. MXS_USERDATA_KEY,
  60. MXS_X25PAD_KEY,
  61. MXS_X25ADDRESS_KEY,
  62. MXS_COMPRESSION_OFF_KEY,
  63. MXS_COMPRESSION_ON_KEY,
  64. MXS_HDWFLOWCONTROL_OFF_KEY,
  65. MXS_HDWFLOWCONTROL_ON_KEY,
  66. MXS_PROTOCOL_OFF_KEY,
  67. MXS_PROTOCOL_ON_KEY,
  68. MXS_SPEAKER_OFF_KEY,
  69. MXS_SPEAKER_ON_KEY,
  70. MXS_AUTODIAL_OFF_KEY,
  71. MXS_AUTODIAL_ON_KEY,
  72. MXS_USERNAME_KEY,
  73. MXS_PASSWORD_KEY,
  74. };
  75. //* Utility Functions ******************************************************
  76. //
  77. //* GetDeviceCB ------------------------------------------------------------
  78. //
  79. // Function: Looks for a Device Control Block in the global Device linked
  80. // list. If no DCB is found that contains an hIOPort matching
  81. // the input parameter, one is created, initalized, and added
  82. // to the list.
  83. //
  84. // Returns: Pointer to the DEVICE_CB which contains an hIOPort matching the
  85. // the second input parameter.
  86. //*
  87. DWORD
  88. GetDeviceCB(HANDLE hIOPort,
  89. char *pszDeviceType,
  90. char *pszDeviceName,
  91. DEVICE_CB **ppDev)
  92. {
  93. DWORD dRC = SUCCESS ;
  94. *ppDev = FindDeviceInList(pDeviceList, hIOPort, pszDeviceType, pszDeviceName);
  95. if (*ppDev == NULL)
  96. {
  97. dRC = AddDeviceToList(&pDeviceList,
  98. hIOPort,
  99. pszDeviceType,
  100. pszDeviceName,
  101. ppDev);
  102. if (dRC != SUCCESS)
  103. goto getdcbend ;
  104. dRC = CreateInfoTable(*ppDev);
  105. if (dRC != SUCCESS)
  106. goto getdcbend ;
  107. dRC = CreateAttributes(*ppDev) ;
  108. }
  109. getdcbend:
  110. return (dRC);
  111. }
  112. //* FindDeviceInList -------------------------------------------------------
  113. //
  114. // Function: Finds the Device Control Block in the global Device linked
  115. // list which contains the hIOPort handle, device type, and
  116. // device name.
  117. //
  118. // Returns: Pointer to the DEVICE_CB which contains matches for the second,
  119. // third, and fourth parameters, or NULL if no such DEVICE_CB
  120. // is found.
  121. //*
  122. DEVICE_CB*
  123. FindDeviceInList(DEVICE_CB *pDev,
  124. HANDLE hIOPort,
  125. TCHAR *pszDeviceType,
  126. TCHAR *pszDeviceName)
  127. {
  128. while (pDev != NULL)
  129. {
  130. pDev = FindPortInList(pDev, hIOPort, NULL);
  131. if (pDev == NULL)
  132. break;
  133. if (_stricmp(pDev->szDeviceType, pszDeviceType) == 0 &&
  134. _stricmp(pDev->szDeviceName, pszDeviceName) == 0)
  135. break;
  136. pDev = pDev->pNextDeviceCB;
  137. }
  138. return(pDev);
  139. }
  140. //* FindPortInList ---------------------------------------------------------
  141. //
  142. // Function: Finds the first Device Control Block in the global Device linked
  143. // list which contains the hIOPort handle.
  144. //
  145. // If pPrevDev is not NULL on input, then on output it *pPrevDev
  146. // points to the DCB just prior to the "found" DCB pointed to by
  147. // the returned pointer. If the function return value is not NULL
  148. // *pPrevDev will be valid.
  149. //
  150. // NOTE: If the found DCB is at the head of the list, pPrevDev
  151. // will be the same as the return value.
  152. //
  153. // Returns: Pointer to the DEVICE_CB which contains an hIOPort matching the
  154. // the second input parameter, or NULL if no such DEVICE_CB is found.
  155. //*
  156. DEVICE_CB*
  157. FindPortInList(DEVICE_CB *pDeviceList, HANDLE hIOPort, DEVICE_CB **pPrevDev)
  158. {
  159. DEVICE_CB *pDev;
  160. pDev = pDeviceList; //Allow for case of only one DCB on list
  161. while(pDeviceList != NULL && pDeviceList->hPort != hIOPort)
  162. {
  163. pDev = pDeviceList;
  164. pDeviceList = pDeviceList->pNextDeviceCB;
  165. }
  166. if (pPrevDev != NULL)
  167. *pPrevDev = pDev;
  168. return(pDeviceList);
  169. }
  170. //* AddDeviceToList --------------------------------------------------------
  171. //
  172. // Function: Creates a Device Control Block and adds it to the head of the
  173. // global Device linked list.
  174. //
  175. // Returns: SUCCESS
  176. // ERROR_UNKNOWN_DEVICE_TYPE
  177. // ERROR_ALLOCATING_MEMORY
  178. //*
  179. DWORD
  180. AddDeviceToList(DEVICE_CB **ppDeviceList,
  181. HANDLE hIOPort,
  182. LPTSTR lpszDeviceType,
  183. LPTSTR lpszDeviceName,
  184. DEVICE_CB **ppDevice)
  185. {
  186. DEVICE_CB *pDev;
  187. DEVICETYPE eDeviceType;
  188. DWORD dRC;
  189. TCHAR szFileName[MAX_PATH];
  190. DEVICE_CB *origpDeviceList ;
  191. origpDeviceList = *ppDeviceList ; // save this pointer since it may be restored later
  192. // Check input
  193. eDeviceType = DeviceTypeStrToEnum(lpszDeviceType);
  194. if (eDeviceType == DT_UNKNOWN)
  195. return(ERROR_UNKNOWN_DEVICE_TYPE);
  196. // INF file sections are opened before the DCB is created because the
  197. // open/close count must be kept balanced even when errors occur. (If
  198. // OpenResponseSection fails it does not increment the count, and because
  199. // the DCB does not exist DeviceWork does not decrement the count.)
  200. // Open global response section for modems
  201. *szFileName = TEXT('\0');
  202. GetInfFileName(lpszDeviceType, szFileName, sizeof(szFileName));
  203. if (eDeviceType == DT_MODEM) {
  204. dRC = OpenResponseSection (szFileName) ;
  205. if (dRC != SUCCESS)
  206. return dRC ;
  207. }
  208. // Put new DCB at head of list
  209. pDev = *ppDeviceList;
  210. GetMem(sizeof(DEVICE_CB), (BYTE **)ppDeviceList);
  211. if (*ppDeviceList == NULL)
  212. return(ERROR_ALLOCATING_MEMORY);
  213. *ppDevice = *ppDeviceList;
  214. (*ppDevice)->pNextDeviceCB = pDev;
  215. // Initialize New Device Control Block
  216. pDev = *ppDevice;
  217. pDev->hPort = hIOPort;
  218. // strcpy(pDev->szDeviceName, lpszDeviceName);
  219. // strcpy(pDev->szDeviceType, lpszDeviceType);
  220. (VOID) StringCchCopyA(pDev->szDeviceName,
  221. MAX_DEVICE_NAME + 1,
  222. lpszDeviceName);
  223. (VOID) StringCchCopyA(pDev->szDeviceType,
  224. MAX_DEVICETYPE_NAME,
  225. lpszDeviceType);
  226. pDev->eDeviceType = eDeviceType;
  227. pDev->pInfoTable = NULL;
  228. pDev->pMacros = NULL;
  229. pDev->hInfFile = INVALID_HRASFILE;
  230. pDev->fPartialResponse = FALSE;
  231. pDev->bErrorControlOn = FALSE;
  232. pDev->Overlapped.RO_Overlapped.Internal = 0;
  233. pDev->Overlapped.RO_Overlapped.InternalHigh = 0;
  234. pDev->Overlapped.RO_Overlapped.Offset = 0;
  235. pDev->Overlapped.RO_Overlapped.OffsetHigh = 0;
  236. pDev->Overlapped.RO_Overlapped.hEvent = NULL;
  237. pDev->Overlapped.RO_EventType = OVEVT_DEV_ASYNCOP;
  238. pDev->dwRetries = 1;
  239. // Initialize State variables
  240. pDev->eDevNextAction = SEND; // DeviceStateMachine() State
  241. pDev->eCmdType = CT_GENERIC; // Used by DeviceStateMachine()
  242. pDev->eNextCmdType = CT_GENERIC; // Used by DeviceStateMachine()
  243. pDev->fEndOfSection = FALSE; // Used by DeviceStateMachine()
  244. pDev->eRcvState = GETECHO; // ReceiveStateMachine() State
  245. // Open device section of INF file
  246. if (FindOpenDevSection (szFileName, lpszDeviceName, &(pDev->hInfFile)) == TRUE)
  247. return SUCCESS ;
  248. dRC = RasDevOpen(szFileName, lpszDeviceName, &(pDev->hInfFile));
  249. if (dRC != SUCCESS) {
  250. // restore the pointers
  251. //
  252. *ppDeviceList = origpDeviceList ;
  253. *ppDevice = NULL ;
  254. free (pDev) ;
  255. return(dRC);
  256. } else
  257. AddOpenDevSection (szFileName, lpszDeviceName, pDev->hInfFile) ; // Add to the opened list
  258. return(SUCCESS);
  259. }
  260. //* CreateInfoTable --------------------------------------------------------
  261. //
  262. // Function: Creates an InfoTable and initalizes it by reading the variables
  263. // and macros found in the INF file into it. The InfoTable is
  264. // attached to the Device Control Block pointed to by the input
  265. // parameter.
  266. //
  267. // This function allocates memory.
  268. //
  269. // Returns: SUCCESS
  270. // ERROR_ALLOCATING_MEMORY
  271. // Return value from RasDevOpen() or RasDevGetParams().
  272. //*
  273. DWORD
  274. CreateInfoTable(DEVICE_CB *pDevice)
  275. {
  276. DWORD dRC, dSize = 0;
  277. RASMAN_DEVICEINFO *pInfoTable = NULL ;
  278. // Read variables and macros into InfoTable from INF file
  279. dRC = RasDevGetParams(pDevice->hInfFile, (BYTE *)(pInfoTable), &dSize);
  280. if (dRC == ERROR_BUFFER_TOO_SMALL)
  281. {
  282. dSize += sizeof(RAS_PARAMS) * NUM_INTERNAL_MACROS;
  283. GetMem(dSize, (BYTE **)&pInfoTable);
  284. if (pInfoTable == NULL)
  285. return(ERROR_ALLOCATING_MEMORY);
  286. dRC = RasDevGetParams(pDevice->hInfFile, (BYTE *)(pInfoTable), &dSize);
  287. }
  288. if (dRC != SUCCESS)
  289. {
  290. free(pInfoTable);
  291. return(dRC);
  292. }
  293. if ((dRC = AddInternalMacros(pDevice, pInfoTable)) != SUCCESS)
  294. {
  295. free(pInfoTable);
  296. return(dRC);
  297. }
  298. // Attach InfoTable to Device Control Block
  299. pDevice->pInfoTable = pInfoTable;
  300. return(SUCCESS);
  301. }
  302. //* AddInternalMacros ------------------------------------------------------
  303. //
  304. // Function: Adds internal macros to existing InfoTable.
  305. //
  306. // Asumptions: The InfoTable buffer was created with room enough for
  307. // the internal macros.
  308. //
  309. // Returns: SUCCESS
  310. // ERROR_ALLOCATING_MEMORY
  311. //*
  312. DWORD
  313. AddInternalMacros(DEVICE_CB *pDev, RASMAN_DEVICEINFO *pDI)
  314. {
  315. WORD i;
  316. RAS_PARAMS *pParam;
  317. // Get pointer to next unused param
  318. pParam = &(pDI->DI_Params[pDI->DI_NumOfParams]);
  319. // Fill in params for internal macros
  320. for (i=0; i<NUM_INTERNAL_MACROS; i++)
  321. {
  322. strcpy(pParam->P_Key, gszInternalMacroNames[i]);
  323. pParam->P_Type = String;
  324. pParam->P_Attributes = 0;
  325. pParam->P_Value.String.Length = 0;
  326. GetMem(1, &(pParam->P_Value.String.Data));
  327. if (pParam->P_Value.String.Data == NULL)
  328. return(ERROR_ALLOCATING_MEMORY);
  329. *(pParam->P_Value.String.Data) = '\0';
  330. pParam++;
  331. }
  332. pDI->DI_NumOfParams += NUM_INTERNAL_MACROS;
  333. return(SUCCESS);
  334. }
  335. //* CreateAttributes -------------------------------------------------------
  336. //
  337. // Function: This function is used to set attributes for the first time
  338. // when the InfoTable is created. UpdateInfoTable() is used
  339. // to later change attributes.
  340. //
  341. // First, all attributes are set according to the parameter
  342. // key with all binary macros being enabled. Then the
  343. // DEFAULTOFF variable is parsed, and macros listed there are
  344. // disabled.
  345. //
  346. // Assumptions: - The ATTRIB_VARIABLE attribute bit has already been set
  347. // by RasDevGetParams().
  348. // - Parameters in InfoTable are sorted by P_Key.
  349. // - Both parts of binary macros are present.
  350. // These assumptions imply that if somename_off is in InfoTable
  351. // somename_on is also present and is adjacent to somename_off.
  352. //
  353. // Returns: SUCCESS
  354. // ERROR_DEFAULTOFF_MACRO_NOT_FOUND
  355. // ERROR_ALLOCATING_MEMORY
  356. // Return codes from PortGetInfo
  357. //*
  358. DWORD
  359. CreateAttributes(DEVICE_CB *pDevice)
  360. {
  361. int iDefaultOff = -1;
  362. DWORD i, dwMemSize;
  363. DWORD dwRC;
  364. BOOL fFound;
  365. TCHAR *lpszDefaultOff, *lpszEOS, szCoreName[MAX_PARAM_KEY_SIZE];
  366. RAS_PARAMS *pParam;
  367. RASMAN_DEVICEINFO *pInfo = pDevice->pInfoTable;
  368. RASMAN_PORTINFO *pPortInfo;
  369. //DebugPrintf(("mxsutils CreateAttributes\n"));
  370. // Set attributes according to Keyword type,
  371. // defaulting user settable parameters to enabled.
  372. for (i=0; i < pInfo->DI_NumOfParams; i++)
  373. {
  374. pParam = &(pInfo->DI_Params[i]);
  375. //DebugPrintf(("%32s %s\n", pParam, pParam->P_Value.String.Data));
  376. if (IsVariable(*pParam))
  377. pParam->P_Attributes = ATTRIB_VARIABLE;
  378. else if (IsBinaryMacro(pParam->P_Key))
  379. pParam->P_Attributes = ATTRIB_BINARYMACRO |
  380. ATTRIB_USERSETTABLE |
  381. ATTRIB_ENABLED;
  382. else
  383. pParam->P_Attributes = ATTRIB_ENABLED;
  384. // Remember location of DEFAULTOFF variable
  385. if (_stricmp(pInfo->DI_Params[i].P_Key, MXS_DEFAULTOFF_KEY) == 0)
  386. iDefaultOff = i;
  387. }
  388. // Call PortGetInfo (first loading the rasser.dll if necessary)
  389. if (PortGetInfo == NULL)
  390. {
  391. if ((dwRC = LoadRasserDll(&PortGetInfo, &PortSetInfo)) != SUCCESS)
  392. return(dwRC);
  393. }
  394. dwMemSize = 256;
  395. GetMem(dwMemSize, (BYTE **)&pPortInfo);
  396. if (pPortInfo == NULL)
  397. return(ERROR_ALLOCATING_MEMORY);
  398. dwRC = PortGetInfo(pDevice->hPort, NULL, (BYTE *)pPortInfo, &dwMemSize);
  399. if (dwRC == ERROR_BUFFER_TOO_SMALL)
  400. {
  401. free(pPortInfo);
  402. GetMem(dwMemSize, (BYTE **)&pPortInfo);
  403. if (pPortInfo == NULL)
  404. return(ERROR_ALLOCATING_MEMORY);
  405. PortGetInfo(pDevice->hPort, NULL, (BYTE *)pPortInfo, &dwMemSize);
  406. }
  407. else if ( dwRC )
  408. {
  409. dwRC = SUCCESS;
  410. return dwRC;
  411. }
  412. dwRC = SUCCESS ;
  413. // Save the Port name in the DCB
  414. GetPcbString(pPortInfo, SER_PORTNAME_KEY, pDevice->szPortName);
  415. // Get the current Bps of the port.
  416. // If the modem does not report the connect bps we will use this one.
  417. GetPcbString(pPortInfo, SER_CONNECTBPS_KEY, pDevice->szPortBps);
  418. // Does serial.ini file contain a DEFAULTOFF variable?
  419. if (!GetPortDefaultOff(pPortInfo, &lpszDefaultOff))
  420. {
  421. // No DEFAULTOFF in port INI file
  422. // Check that DEFAULTOFF variable was found in device Info table
  423. if (iDefaultOff == -1) //DEFAULTOFF not found
  424. { //Assume none are to be disabled
  425. free(pPortInfo);
  426. return(SUCCESS);
  427. }
  428. lpszDefaultOff = pInfo->DI_Params[iDefaultOff].P_Value.String.Data;
  429. }
  430. // Prepare DEFALULTOFF string
  431. InitParameterStr(lpszDefaultOff, &lpszEOS);
  432. // Disable parameters listed in DEFAULTOFF variable.
  433. while (lpszDefaultOff < lpszEOS)
  434. {
  435. fFound = FALSE;
  436. for (i=0; i < pInfo->DI_NumOfParams; i++)
  437. {
  438. if (IsBinaryMacro(pInfo->DI_Params[i].P_Key))
  439. {
  440. GetCoreMacroName(pInfo->DI_Params[i].P_Key, szCoreName);
  441. if (_stricmp(lpszDefaultOff, szCoreName) == 0)
  442. {
  443. pInfo->DI_Params[i].P_Attributes &= ~ATTRIB_ENABLED; //One suffix
  444. pInfo->DI_Params[i+1].P_Attributes &= ~ATTRIB_ENABLED; //Other suffix
  445. fFound = TRUE;
  446. break;
  447. }
  448. }
  449. }
  450. if (!fFound)
  451. {
  452. free(pPortInfo);
  453. return(ERROR_DEFAULTOFF_MACRO_NOT_FOUND);
  454. }
  455. GetNextParameter(&lpszDefaultOff, lpszEOS);
  456. }
  457. free(pPortInfo);
  458. return(SUCCESS);
  459. }
  460. //* GetPortDefaultOff ------------------------------------------------------
  461. //
  462. // Function: This function finds the DEFAULTOFF key in the RASMAN_PORTINFO
  463. // table supplied by the first parameter. A pointer to the value
  464. // string is the output in the second parameter.
  465. //
  466. // If the DEFAULTOFF key is not found, the function returns FALSE,
  467. // and the second parameter is undefined.
  468. //
  469. // Arguments:
  470. // pPortInfo IN Pointer to Port Info Table from PortGetInfo()
  471. // lpszValue OUT DEFAULTOFF value string
  472. //
  473. // Returns: TRUE if DEFAULTOFF key is found, otherwise FALSE
  474. //
  475. //*
  476. BOOL
  477. GetPortDefaultOff(RASMAN_PORTINFO *pPortInfo, TCHAR **lpszValue)
  478. {
  479. WORD i;
  480. for (i=0; i<pPortInfo->PI_NumOfParams; i++)
  481. if (_stricmp(SER_DEFAULTOFFSTR_KEY, pPortInfo->PI_Params[i].P_Key) == 0)
  482. break;
  483. if (i >= pPortInfo->PI_NumOfParams)
  484. return(FALSE);
  485. *lpszValue = pPortInfo->PI_Params[i].P_Value.String.Data;
  486. return(TRUE);
  487. }
  488. //* GetPcbString -----------------------------------------------------------
  489. //
  490. // Funciton: Searches a RASMAN_PORTINFO struct for a P_Key that matches
  491. // the second parameter, pszPcbKey. The P_Value.String.Data
  492. // is copied to the third parameter, pszDest which is the
  493. // output parameter.
  494. //
  495. // Note: This function may only be called for keys that have
  496. // P_Type String values (and never for P_Type Number values).
  497. //
  498. // Assumptions: The first parameter has been initalize by a call to
  499. // PortGetInfo.
  500. //
  501. // Returns: nothing.
  502. //
  503. //*
  504. void
  505. GetPcbString(RASMAN_PORTINFO *pPortInfo, char *pszPcbKey, char *pszDest)
  506. {
  507. WORD i;
  508. for (i=0; i<pPortInfo->PI_NumOfParams; i++)
  509. if (_stricmp(pszPcbKey, pPortInfo->PI_Params[i].P_Key) == 0)
  510. break;
  511. if (i >= pPortInfo->PI_NumOfParams ||
  512. pPortInfo->PI_Params[i].P_Type != String)
  513. return;
  514. strncpy(pszDest,
  515. pPortInfo->PI_Params[i].P_Value.String.Data,
  516. pPortInfo->PI_Params[i].P_Value.String.Length);
  517. *(pszDest + pPortInfo->PI_Params[i].P_Value.String.Length) = '\0';
  518. }
  519. //* UpdateInfoTable --------------------------------------------------------
  520. //
  521. // Function: This function is used to update attributes when DeviceSetInfo()
  522. // is called. The nested for loops search the Info Table for each
  523. // input param to be set.
  524. //
  525. // If the full macro name (including _off or _on for binary macros)
  526. // is given in the input P_Key, the P_Value is copied and the
  527. // Enable bit in P_Attributes is copied. If the core name
  528. // is given for binary macros, only the Enable bit is copied.
  529. //
  530. // Assumptions: - Parameters in InfoTable are sorted by P_Key.
  531. // - Both parts of binary macros are present in the InfoTable.
  532. // These assumptions imply that if somename_off is in InfoTable
  533. // somename_on is also present and is adjacent to somename_off.
  534. //
  535. // Pseudo Code: for (each input param to be set)
  536. // for (each item in InfoTable)
  537. // if (P_Keys match && !IsVariable)
  538. // copy P_Value
  539. // copy Enable Attribute bit
  540. // else if (P_Keys binary macro core names match)
  541. // copy Enable Attribute bit
  542. //
  543. // Returns: SUCCESS
  544. // ERROR_WRONG_KEY_SPECIFIED
  545. //
  546. //*
  547. DWORD
  548. UpdateInfoTable(DEVICE_CB *pDevice, RASMAN_DEVICEINFO *pNewInfo)
  549. {
  550. WORD i, j;
  551. BOOL fFound;
  552. DWORD dwRC, dwSrcLen, dwNumber;
  553. TCHAR *pszSrc, szNumberStr[MAX_LEN_STR_FROM_NUMBER + 1];
  554. RASMAN_DEVICEINFO *pInfoTable = pDevice->pInfoTable;
  555. for (i=0; i < pNewInfo->DI_NumOfParams; i++) //For each param to set,
  556. {
  557. fFound = FALSE;
  558. for (j=0; j < pInfoTable->DI_NumOfParams; j++) //check InfoTable entries
  559. {
  560. // Check for unary macro match
  561. if (IsUnaryMacro(pInfoTable->DI_Params[j]) &&
  562. _stricmp(pNewInfo->DI_Params[i].P_Key,
  563. pInfoTable->DI_Params[j].P_Key) == 0)
  564. {
  565. // Check format of P_Value field; convert to string if necessary
  566. if (pNewInfo->DI_Params[i].P_Type == String)
  567. {
  568. pszSrc = pNewInfo->DI_Params[i].P_Value.String.Data;
  569. dwSrcLen = pNewInfo->DI_Params[i].P_Value.String.Length;
  570. }
  571. else
  572. { //P_Type == Number
  573. _itoa(pNewInfo->DI_Params[i].P_Value.Number,
  574. szNumberStr,
  575. 10);
  576. pszSrc = szNumberStr;
  577. dwSrcLen = strlen(szNumberStr);
  578. }
  579. // Copy P_Value (allocating more memory as necessary)
  580. dwRC = UpdateParamString(&(pInfoTable->DI_Params[j]),
  581. pszSrc,
  582. dwSrcLen);
  583. if (dwRC != SUCCESS)
  584. return(dwRC);
  585. fFound = TRUE;
  586. break;
  587. }
  588. // Check for Binary Macro match
  589. else if(CoreMacroNameMatch(pNewInfo->DI_Params[i].P_Key,
  590. pInfoTable->DI_Params[j].P_Key))
  591. {
  592. // Convert string to number, if necessary
  593. if (pNewInfo->DI_Params[i].P_Type == String)
  594. {
  595. strncpy(szNumberStr,
  596. pNewInfo->DI_Params[i].P_Value.String.Data,
  597. pNewInfo->DI_Params[i].P_Value.String.Length);
  598. szNumberStr[pNewInfo->DI_Params[i].P_Value.String.Length] = '\0';
  599. dwNumber = atoi(szNumberStr);
  600. }
  601. else
  602. dwNumber = pNewInfo->DI_Params[i].P_Value.Number;
  603. // Set macro enabled bit in Attributes field
  604. if (dwNumber == 0)
  605. {
  606. pInfoTable->DI_Params[j].P_Attributes &= ~ATTRIB_ENABLED; //Clear bit
  607. pInfoTable->DI_Params[j+1].P_Attributes &= ~ATTRIB_ENABLED;
  608. }
  609. else
  610. {
  611. pInfoTable->DI_Params[j].P_Attributes |= ATTRIB_ENABLED; //Set bit
  612. pInfoTable->DI_Params[j+1].P_Attributes |= ATTRIB_ENABLED;
  613. }
  614. fFound = TRUE;
  615. break;
  616. }
  617. }
  618. if (!fFound)
  619. return(ERROR_WRONG_KEY_SPECIFIED);
  620. }
  621. return(SUCCESS);
  622. }
  623. //* DeviceAttachedToPort ---------------------------------------------------
  624. //
  625. // Funciton: Searched through a port info block for DeviceType and
  626. // DeviceName and compares the found strings to the second
  627. // and third input parameters.
  628. //
  629. // Assumptions: The first parameter has been initalize by a call to
  630. // PortGetInfo.
  631. // SER_DEVCIETYPE_KEY and SER_DEVICENAME_KEY each appear
  632. // only once in the RASMAN_PORTINFO block.
  633. //
  634. // Returns: TRUE if pszDeviceType and pszDeviceName are found in
  635. // pPortInfo, else FALSE.
  636. //*
  637. BOOL
  638. DeviceAttachedToPort(RASMAN_PORTINFO *pPortInfo,
  639. char *pszDeviceType,
  640. char *pszDeviceName)
  641. {
  642. WORD i;
  643. BOOL bTypeMatch = FALSE, bNameMatch = FALSE;
  644. for (i=0; i<pPortInfo->PI_NumOfParams; i++)
  645. {
  646. if (_stricmp(SER_DEVICETYPE_KEY, pPortInfo->PI_Params[i].P_Key) == 0)
  647. {
  648. if ( strlen(pszDeviceType) ==
  649. pPortInfo->PI_Params[i].P_Value.String.Length
  650. &&
  651. _strnicmp(pszDeviceType,
  652. pPortInfo->PI_Params[i].P_Value.String.Data,
  653. pPortInfo->PI_Params[i].P_Value.String.Length) == 0)
  654. bTypeMatch = TRUE;
  655. else
  656. break;
  657. }
  658. if (_stricmp(SER_DEVICENAME_KEY, pPortInfo->PI_Params[i].P_Key) == 0)
  659. {
  660. if ( strlen(pszDeviceName) ==
  661. pPortInfo->PI_Params[i].P_Value.String.Length
  662. &&
  663. _strnicmp(pszDeviceName,
  664. pPortInfo->PI_Params[i].P_Value.String.Data,
  665. pPortInfo->PI_Params[i].P_Value.String.Length) == 0)
  666. bNameMatch = TRUE;
  667. else
  668. break;
  669. }
  670. if (bTypeMatch && bNameMatch)
  671. break;
  672. }
  673. return(bTypeMatch && bNameMatch);
  674. }
  675. //* CreateDefaultOffString -------------------------------------------------
  676. //
  677. // Funciton:
  678. // DeviceName and compares the found strings to the second
  679. // and third input parameters.
  680. //
  681. // Assumptions: Buffer pointed to by pszDefaultOff is large enough for
  682. // all DefaultOff macros.
  683. //
  684. // Returns: Nothing
  685. //*
  686. void
  687. CreateDefaultOffString(DEVICE_CB *pDev, char *pszDefaultOff)
  688. {
  689. WORD i, k, wLen;
  690. char *szDefaultOffMacros[] = { MXS_SPEAKER_KEY ,
  691. MXS_HDWFLOWCONTROL_KEY ,
  692. MXS_PROTOCOL_KEY ,
  693. MXS_COMPRESSION_KEY };
  694. *pszDefaultOff = '\0';
  695. // Find each macro and if it is off then add its name to DefaultOff string
  696. for (i=0; i < sizeof(szDefaultOffMacros)/sizeof(char *); i++)
  697. {
  698. k = (WORD) FindTableEntry(pDev->pInfoTable, szDefaultOffMacros[i]);
  699. if (k == INVALID_INDEX)
  700. continue;
  701. // If macro is turned off then copy its key to the DefaultOff string
  702. if ( ! (pDev->pInfoTable->DI_Params[k].P_Attributes & ATTRIB_ENABLED))
  703. {
  704. strcat(pszDefaultOff, szDefaultOffMacros[i]);
  705. strcat(pszDefaultOff, " "); //Add deliminting space
  706. }
  707. }
  708. // Remove last delimiting space
  709. wLen = (WORD)strlen(pszDefaultOff);
  710. if (wLen > 0)
  711. pszDefaultOff[wLen - 1] = '\0';
  712. }
  713. //* BuildOutputTable -------------------------------------------------------
  714. //
  715. // Function: Copies macros from internal InfoTable to the caller's buffer.
  716. // For Parameter: Function copies:
  717. // Variable Entire RASMAN_DEVICEINFO struct
  718. // Unary Macro Entire RASMAN_DEVICEINFO struct
  719. // Binary Macro Everything except P_Value field
  720. //
  721. // Assumptions: - Output buffer will ALWAYS be large enough.
  722. // - Parameters in InfoTable are sorted by P_Key (except
  723. // internal macros).
  724. // - Both parts of binary macros are present.
  725. // These assumptions imply that if somename_off is in InfoTable
  726. // somename_on is also present and is adjacent to somename_off.
  727. //
  728. // Returns: SUCCESS
  729. // ERROR_BUFFER_TOO_SMALL
  730. //
  731. //*
  732. DWORD
  733. BuildOutputTable(DEVICE_CB *pDevice, BYTE *pInfo, DWORD *pdwSize)
  734. {
  735. WORD i, j;
  736. DWORD cOutputParams = 0;
  737. LPTCH pValue;
  738. TCHAR szCoreName[MAX_PARAM_KEY_SIZE];
  739. RASMAN_DEVICEINFO *pInfoTable = pDevice->pInfoTable,
  740. *pOutputTable = (RASMAN_DEVICEINFO *)pInfo;
  741. // Compute location of first value string (follows RAS_PARAMS)
  742. cOutputParams =
  743. pInfoTable->DI_NumOfParams - MacroCount(pInfoTable, BINARY_MACROS);
  744. *pdwSize =
  745. sizeof(RASMAN_DEVICEINFO) + sizeof(RAS_PARAMS) * (cOutputParams - 1);
  746. pValue = pInfo + *pdwSize;
  747. // Set NumOfParams
  748. pOutputTable->DI_NumOfParams = cOutputParams;
  749. // Copy macros
  750. for (i=0, j=0; i < pInfoTable->DI_NumOfParams; i++)
  751. {
  752. if (IsBinaryMacro(pInfoTable->DI_Params[i].P_Key))
  753. {
  754. // copy core macro name, Type, and Attributes, but not Value
  755. GetCoreMacroName(pInfoTable->DI_Params[i].P_Key, szCoreName);
  756. strcpy(pOutputTable->DI_Params[j].P_Key, szCoreName);
  757. pOutputTable->DI_Params[j].P_Type = pInfoTable->DI_Params[i].P_Type;
  758. pOutputTable->DI_Params[j].P_Attributes =
  759. pInfoTable->DI_Params[i].P_Attributes;
  760. pOutputTable->DI_Params[j].P_Value.String.Data = pValue;
  761. *pValue++ = '\0';
  762. pOutputTable->DI_Params[j].P_Value.String.Length = 0;
  763. i++;
  764. j++;
  765. }
  766. else // Is Unary Macro or Variable
  767. {
  768. // copy everything including Value
  769. pOutputTable->DI_Params[j] = pInfoTable->DI_Params[i];
  770. pOutputTable->DI_Params[j].P_Value.String.Data = pValue;
  771. strncpy(pValue, pInfoTable->DI_Params[i].P_Value.String.Data,
  772. pInfoTable->DI_Params[i].P_Value.String.Length);
  773. pOutputTable->DI_Params[j].P_Value.String.Length
  774. = pInfoTable->DI_Params[i].P_Value.String.Length;
  775. pValue += pInfoTable->DI_Params[i].P_Value.String.Length;
  776. *pValue++ = '\0';
  777. j++;
  778. }
  779. }
  780. *pdwSize = (DWORD) (pValue - pInfo);
  781. return(SUCCESS);
  782. }
  783. //* ConnectListen() --------------------------------------------------------
  784. //
  785. // Function: Worker routine for DeviceConnect and DeviceListen.
  786. //
  787. // Returns: ERROR_NO_COMMAND_FOUND
  788. // ERROR_STATE_MACHINES_ALREADY_STARTED
  789. // and codes returned by DeviceStateMachine()
  790. //*
  791. DWORD
  792. ConnectListen(HANDLE hIOPort,
  793. char *pszDeviceType,
  794. char *pszDeviceName,
  795. CMDTYPE eCmd)
  796. {
  797. DWORD dRC;
  798. DEVICE_CB *pDevice;
  799. // Get Device Control Block for this hIOPort
  800. dRC = GetDeviceCB(hIOPort, pszDeviceType, pszDeviceName, &pDevice);
  801. if (dRC != SUCCESS)
  802. return(dRC);
  803. // Check that DeviceStateMachine is not started (but is reset)
  804. if (pDevice->eDevNextAction != SEND)
  805. return(ERROR_STATE_MACHINES_ALREADY_STARTED);
  806. // Create Macro Translation Table for use by RasDevAPIs
  807. if ((dRC = BuildMacroXlationTable(pDevice)) != SUCCESS)
  808. return(dRC);
  809. // Do the next block only once for most devices,
  810. // but retry a few times when getting modem hardware errors
  811. do
  812. {
  813. // Initialize command types
  814. switch(RasDevIdFirstCommand(pDevice->hInfFile))
  815. {
  816. case CT_INIT:
  817. pDevice->eCmdType = CT_INIT;
  818. pDevice->eNextCmdType = eCmd;
  819. break;
  820. case CT_DIAL: //If 1st cmd is DIAL or LISTEN assume
  821. case CT_LISTEN: //the other is also present
  822. pDevice->eCmdType = eCmd;
  823. break;
  824. case CT_GENERIC:
  825. pDevice->eCmdType = CT_GENERIC;
  826. break;
  827. default:
  828. return(ERROR_NO_COMMAND_FOUND);
  829. }
  830. // Reseting state variables and purging com ports are not needed on
  831. // first time through loop, but are need on subsequent loops.
  832. // Reset state variables to initial values
  833. pDevice->eDevNextAction = SEND;
  834. pDevice->eRcvState = GETECHO;
  835. // Cancel any pending com port action and purge com buffers
  836. PurgeComm(hIOPort,
  837. PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
  838. // Start state machine
  839. dRC = DeviceStateMachine(pDevice, hIOPort);
  840. } while(dRC == ERROR_PORT_OR_DEVICE &&
  841. pDevice->eDeviceType == DT_MODEM &&
  842. pDevice->dwRetries++ < MODEM_RETRIES );
  843. return(dRC);
  844. }
  845. //* DeviceTypeStrToEnum ----------------------------------------------------
  846. //
  847. // Function: Converts a device type string into a device type enum.
  848. //
  849. // Returns: The device type code.
  850. //
  851. //*
  852. DEVICETYPE
  853. DeviceTypeStrToEnum(LPTSTR lpszDeviceType)
  854. {
  855. if (_strnicmp(lpszDeviceType, MXS_NULL_TXT, MAX_DEVICETYPE_NAME) == 0)
  856. return(DT_NULL);
  857. if (_strnicmp(lpszDeviceType, MXS_MODEM_TXT, MAX_DEVICETYPE_NAME) == 0)
  858. return(DT_MODEM);
  859. if (_strnicmp(lpszDeviceType, MXS_PAD_TXT, MAX_DEVICETYPE_NAME) == 0)
  860. return(DT_PAD);
  861. if (_strnicmp(lpszDeviceType, MXS_SWITCH_TXT, MAX_DEVICETYPE_NAME) == 0)
  862. return(DT_SWITCH);
  863. return(DT_UNKNOWN);
  864. }
  865. //* GetInfFileName ---------------------------------------------------------
  866. //
  867. // Function: Converts a device type string into the full path name for the
  868. // appropriate INF file.
  869. //
  870. // The RAS_PATH define contains leading and trailin backslashes.
  871. // It looks like "\\RAS\\".
  872. //
  873. // Returns: Nothing.
  874. //
  875. //*
  876. void
  877. GetInfFileName(LPTSTR pszDeviceType, LPTSTR pszFileName, DWORD dwFileNameLen)
  878. {
  879. UINT uLen;
  880. uLen = GetSystemDirectory(pszFileName, dwFileNameLen);
  881. strcat(pszFileName, RAS_PATH);
  882. switch(DeviceTypeStrToEnum(pszDeviceType))
  883. {
  884. case DT_NULL:
  885. case DT_MODEM:
  886. strcat(pszFileName, MODEM_INF_FILENAME);
  887. break;
  888. case DT_PAD:
  889. strcat(pszFileName, PAD_INF_FILENAME);
  890. break;
  891. case DT_SWITCH:
  892. strcat(pszFileName, SWITCH_INF_FILENAME);
  893. break;
  894. default:
  895. strcat(pszFileName, "");
  896. }
  897. }
  898. //* IsVariable -------------------------------------------------------------
  899. //
  900. // Function: Returns TRUE if parameter's "Variable" attribute bit is set.
  901. // Note that FALSE implies that the paramater is a macro.
  902. //
  903. //*
  904. BOOL
  905. IsVariable(RAS_PARAMS Param)
  906. {
  907. return(ATTRIB_VARIABLE & Param.P_Attributes);
  908. }
  909. //* IsUnaryMacro -----------------------------------------------------------
  910. //
  911. // Function: Returns TRUE if param is a unary macro, otherwise FALSE.
  912. //
  913. //*
  914. BOOL
  915. IsUnaryMacro(RAS_PARAMS Param)
  916. {
  917. return(!IsVariable(Param) && !IsBinaryMacro(Param.P_Key));
  918. }
  919. //* IsBinaryMacro ----------------------------------------------------------
  920. //
  921. // Function: Returns TRUE if the string ends with off suffix or on suffix.
  922. //
  923. // FALSE inmplies that the string is a unary macro or a variable
  924. // name.
  925. //
  926. //*
  927. BOOL
  928. IsBinaryMacro(TCHAR *pch)
  929. {
  930. return((BOOL)BinarySuffix(pch));
  931. }
  932. //* BinarySuffix -----------------------------------------------------------
  933. //
  934. // Function: This function indicates whether the input string ends in
  935. // _off or _on.
  936. //
  937. // Returns: ON_SUFFIX, OFF_SUFFIX, or FALSE if neither is the case
  938. //
  939. //*
  940. WORD
  941. BinarySuffix(TCHAR *pch)
  942. {
  943. while (*pch != '\0')
  944. pch++;
  945. pch -= strlen(MXS_ON_SUFX);
  946. if (_stricmp(pch, MXS_ON_SUFX) == 0)
  947. return(ON_SUFFIX);
  948. while (*pch != '\0')
  949. pch++;
  950. pch -= strlen(MXS_OFF_SUFX);
  951. if (_stricmp(pch, MXS_OFF_SUFX) == 0)
  952. return(OFF_SUFFIX);
  953. return(FALSE);
  954. }
  955. //* GetCoreMacroName -------------------------------------------------------
  956. //
  957. // Function: Copies FullName to CoreName, but omits the angle brackets, <>,
  958. // for all macros, and omits the "_ON" or "_OFF" suffix for binary
  959. // macros.
  960. //
  961. // Returns: SUCCESS
  962. // ERROR_NOT_BINARY_MACRO
  963. //
  964. //*
  965. DWORD
  966. GetCoreMacroName(LPTSTR lpszFullName, LPTSTR lpszCoreName)
  967. {
  968. LPTCH lpch;
  969. strcpy(lpszCoreName, lpszFullName); // Copy FullName
  970. lpch = lpszCoreName;
  971. while (*lpch != '\0') // Check for _ON suffix
  972. lpch++;
  973. lpch -= strlen(MXS_ON_SUFX);
  974. if (_stricmp(lpch, MXS_ON_SUFX) == 0)
  975. {
  976. *lpch = '\0';
  977. return(SUCCESS);
  978. }
  979. while (*lpch != '\0') // Check for _OFF suffix
  980. lpch++;
  981. lpch -= strlen(MXS_OFF_SUFX);
  982. if (_stricmp(lpch, MXS_OFF_SUFX) == 0)
  983. {
  984. *lpch = '\0';
  985. return(SUCCESS);
  986. }
  987. return(ERROR_NOT_BINARY_MACRO);
  988. }
  989. //* CoreMacroNameMatch -----------------------------------------------------
  990. //
  991. // Function: Assumes that lpszShortName is in the form of a unary macro
  992. // name, <macro>, and that lpszFullName is a binary macro.
  993. // If either assumption is false the function returns FALSE.
  994. // Only if the names (without the angle brackets, <>, and without
  995. // the _on or _off suffixes) match exactly is TRUE returned.
  996. //
  997. // <speaker> will match <speaker_off> or <speaker_on>, but
  998. // will not match <speakers_off>.
  999. //
  1000. // Returns: TRUE/FALSE
  1001. //
  1002. //*
  1003. BOOL
  1004. CoreMacroNameMatch(LPTSTR lpszShortName, LPTSTR lpszFullName)
  1005. {
  1006. TCHAR szCoreName[MAX_PARAM_KEY_SIZE];
  1007. DWORD dRC;
  1008. dRC = GetCoreMacroName(lpszFullName, szCoreName);
  1009. if (dRC != SUCCESS)
  1010. return(FALSE);
  1011. return(_stricmp(lpszShortName, szCoreName) == 0);
  1012. }
  1013. //* InitParameterStr -------------------------------------------------------
  1014. //
  1015. // Function: Changes all spaces in the first parameter to NULL characters.
  1016. // On return the second parameter is a pointer to the NULL
  1017. // character at the end of the input string.
  1018. //
  1019. // This function converts space separated parameters into NULL
  1020. // terminated strings. GetNextParameter() is then used to move
  1021. // a pointer from one string to the next.
  1022. //
  1023. // Caution: This function alters the input string.
  1024. //
  1025. // Returns: Nothing.
  1026. //
  1027. //*
  1028. void
  1029. InitParameterStr(TCHAR *pch, TCHAR **ppchEnd)
  1030. {
  1031. while (*pch != '\0')
  1032. {
  1033. if ((*pch == ' ') || (*pch == ','))
  1034. *pch = '\0';
  1035. pch++;
  1036. }
  1037. *ppchEnd = pch;
  1038. }
  1039. //* GetNextParameter -------------------------------------------------------
  1040. //
  1041. // Function: If the first parameter points to a consecutive series of null
  1042. // terminated strings, this function advances the first parameter
  1043. // to the beginning of the next null terminated string.
  1044. // It will not move past the second parameter which is a pointer
  1045. // to the end of the consecutive series.
  1046. //
  1047. // Returns: Nothing.
  1048. //
  1049. //*
  1050. void
  1051. GetNextParameter(TCHAR **ppch, TCHAR *pchEnd)
  1052. {
  1053. while (**ppch != '\0') //Move to next zero character
  1054. (*ppch)++;
  1055. while (*ppch < pchEnd && **ppch == '\0') //Move to 1st char of next substr
  1056. (*ppch)++;
  1057. }
  1058. //* MacroCount -------------------------------------------------------------
  1059. //
  1060. // Function: This function returns a count of macros in the RASMAN_DEVICEINFO
  1061. // struct that the input parameter points to.
  1062. // ALL_MACROS: Unary and binary macros are counted.
  1063. // BINARY_MACRO: Only binary macros are counted.
  1064. // In either case the ON and OFF parts of a binary macro
  1065. // together count as one macro (not two).
  1066. //
  1067. // Returns: Count of macros in *pInfo.
  1068. //
  1069. //*
  1070. WORD
  1071. MacroCount(RASMAN_DEVICEINFO *pInfo, WORD wType)
  1072. {
  1073. WORD i, cMacros;
  1074. for(i=0, cMacros=0; i < pInfo->DI_NumOfParams; i++)
  1075. {
  1076. if (IsVariable(pInfo->DI_Params[i]))
  1077. ;
  1078. else if (IsBinaryMacro(pInfo->DI_Params[i].P_Key))
  1079. {
  1080. i++; // Step thru each part of a binary macro
  1081. cMacros++; // But count only once
  1082. }
  1083. else // Unary macro
  1084. if (wType == ALL_MACROS)
  1085. cMacros++;
  1086. }
  1087. return(cMacros);
  1088. }
  1089. //* CmdTypeToStr -----------------------------------------------------------
  1090. //
  1091. // Function: This function takes an enum CMDTYPE and converts it to a
  1092. // zero terminated ASCII string which it places in the buffer
  1093. // passed in the first parameter.
  1094. //
  1095. // Returns: Pointer to first parameter
  1096. //
  1097. //*
  1098. PTCH
  1099. CmdTypeToStr(PTCH pszStr, CMDTYPE eCmdType)
  1100. {
  1101. switch(eCmdType)
  1102. {
  1103. case CT_GENERIC:
  1104. *pszStr = '\0';
  1105. break;
  1106. case CT_INIT:
  1107. strcpy(pszStr, "_INIT");
  1108. break;
  1109. case CT_DIAL:
  1110. strcpy(pszStr, "_DIAL");
  1111. break;
  1112. case CT_LISTEN:
  1113. strcpy(pszStr, "_LISTEN");
  1114. break;
  1115. }
  1116. return(pszStr);
  1117. }
  1118. //* IsLoggingOn -----------------------------------------------------------
  1119. //
  1120. // Funciton: Reads the registry to determine if the device dialog is to
  1121. // be logged in a file.
  1122. //
  1123. // Returns: TRUE if logging is to take place; otherwise FALSE
  1124. //
  1125. //*
  1126. BOOL
  1127. IsLoggingOn(void)
  1128. {
  1129. HKEY hKey;
  1130. LONG lRC;
  1131. DWORD dwType, dwValue, dwValueSize = sizeof(dwValue);
  1132. lRC = RegOpenKey(HKEY_LOCAL_MACHINE, RASMAN_REGISTRY_PATH, &hKey);
  1133. if (lRC != ERROR_SUCCESS)
  1134. return(FALSE);
  1135. lRC = RegQueryValueEx(hKey,
  1136. RASMAN_LOGGING_VALUE,
  1137. NULL,
  1138. &dwType,
  1139. (LPBYTE)&dwValue,
  1140. &dwValueSize);
  1141. RegCloseKey(hKey);
  1142. if (lRC != ERROR_SUCCESS)
  1143. return(FALSE);
  1144. if (dwType != REG_DWORD)
  1145. return(FALSE);
  1146. return(dwValue ? TRUE : FALSE);
  1147. }
  1148. //* InitLog ---------------------------------------------------------------
  1149. //
  1150. // Funciton: Opens the log file in overwrite mode and writes a header
  1151. // which includes date and time.
  1152. //
  1153. // Returns: Nothing.
  1154. //
  1155. //*
  1156. void
  1157. InitLog(void)
  1158. {
  1159. TCHAR szBuffer[MAX_CMD_BUF_LEN];
  1160. int iSize;
  1161. DWORD dwBytesWritten;
  1162. SYSTEMTIME st;
  1163. // Create log file path
  1164. GetSystemDirectory(szBuffer, sizeof(szBuffer));
  1165. strcat(szBuffer, RAS_PATH);
  1166. strcat(szBuffer, LOG_FILENAME);
  1167. ghLogFile = CreateFile(szBuffer,
  1168. GENERIC_WRITE,
  1169. FILE_SHARE_READ,
  1170. NULL,
  1171. CREATE_ALWAYS,
  1172. FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,
  1173. NULL);
  1174. if (ghLogFile == INVALID_HANDLE_VALUE)
  1175. {
  1176. gbLogDeviceDialog = FALSE;
  1177. return;
  1178. }
  1179. // Create header
  1180. GetLocalTime(&st);
  1181. iSize = sprintf(szBuffer,
  1182. "Remote Access Service Device Log %02d/%02d/%d %02d:%02d:%02d\r\n",
  1183. st.wMonth, st.wDay, st.wYear, st.wHour, st.wMinute, st.wSecond);
  1184. WriteFile(ghLogFile, szBuffer, (DWORD)iSize, &dwBytesWritten, NULL);
  1185. strcpy(szBuffer,
  1186. "---------------------------------------------------------------\r\n\r\n");
  1187. WriteFile(ghLogFile, szBuffer, strlen(szBuffer), &dwBytesWritten, NULL);
  1188. }
  1189. //* LogString -------------------------------------------------------------
  1190. //
  1191. // Funciton: Writes label and string to the Device Log file.
  1192. //
  1193. // Assumptions: Total length of labels and port handle string will be < 80
  1194. // characters.
  1195. //
  1196. // Returns: nothing.
  1197. //
  1198. //*
  1199. void
  1200. LogString(DEVICE_CB *pDev, TCHAR *pszLabel, TCHAR *psString, DWORD dwStringLen)
  1201. {
  1202. TCHAR sBuffer[MAX_CMD_BUF_LEN + 80];
  1203. TCHAR szPortLabel[] = "Port:";
  1204. DWORD dwBytesWritten, dwTotalLen;
  1205. // If file is getting large, start over with new file
  1206. if (GetFileSize(ghLogFile, NULL) > 100000)
  1207. {
  1208. CloseHandle(ghLogFile);
  1209. InitLog();
  1210. }
  1211. strcpy(sBuffer, szPortLabel);
  1212. dwTotalLen = strlen(szPortLabel);
  1213. strcpy(sBuffer + dwTotalLen, pDev->szPortName);
  1214. dwTotalLen += strlen(pDev->szPortName);
  1215. strcpy(sBuffer + dwTotalLen, " ");
  1216. dwTotalLen++;
  1217. strcpy(sBuffer + dwTotalLen, pszLabel);
  1218. dwTotalLen += strlen(pszLabel);
  1219. memcpy(sBuffer + dwTotalLen, psString, dwStringLen);
  1220. dwTotalLen += dwStringLen;
  1221. strcpy(sBuffer + dwTotalLen, "\r\n");
  1222. dwTotalLen += 2;
  1223. WriteFile(ghLogFile, sBuffer, dwTotalLen, &dwBytesWritten, NULL);
  1224. }
  1225. //* CheckForOverruns -------------------------------------------------------
  1226. //
  1227. // Funciton: Checks for com port overrun errors.
  1228. //
  1229. // Assumptions: Com port errors have been cleared before rasmxs dll APIs
  1230. // are called, that is, serial dll API PortInit was called
  1231. // prior to using the port, or PortClose and PortOpen were
  1232. // called.
  1233. //
  1234. // Returns: TRUE if an overrun error has occured; otherwise FALSE.
  1235. //
  1236. //*
  1237. BOOL
  1238. CheckForOverruns(HANDLE hIOPort)
  1239. {
  1240. DWORD dwErrors = 0;
  1241. ClearCommError(hIOPort, &dwErrors, NULL);
  1242. return((dwErrors & CE_OVERRUN) ? TRUE : FALSE);
  1243. }
  1244. //* LoadRasserDll ---------------------------------------------------------
  1245. //
  1246. // Funciton: Loads rasser.dll and gets entry points for two APIs.
  1247. //
  1248. // Returns: SUCCESS
  1249. // ERROR_PORT_NOT_CONFIGURED
  1250. //*
  1251. DWORD
  1252. LoadRasserDll(PortGetInfo_t *pPortGetInfo, PortSetInfo_t *pPortSetInfo)
  1253. {
  1254. HANDLE hLib;
  1255. // Load DLL
  1256. hLib = LoadLibrary(SERIAL_DLL_FILENAME);
  1257. if (hLib == NULL)
  1258. {
  1259. LogError(ROUTERLOG_CANNOT_LOAD_SERIAL_DLL, 0, NULL, NO_ERROR);
  1260. return(ERROR_PORT_NOT_CONFIGURED);
  1261. }
  1262. // Get entry points
  1263. // Note: Create a new, more appropriate error code to use here,
  1264. // such as, ERROR_CORRUPT_DLL.
  1265. PortSetInfo = (PortSetInfo_t) GetProcAddress(hLib, "PortSetInfo");
  1266. if (PortSetInfo == NULL)
  1267. return(ERROR_PORT_NOT_CONFIGURED);
  1268. PortGetInfo = (PortGetInfo_t) GetProcAddress(hLib, "PortGetInfo");
  1269. if (PortGetInfo == NULL)
  1270. return(ERROR_PORT_NOT_CONFIGURED);
  1271. return(SUCCESS);
  1272. }
  1273. //* OpenResponseSection ---------------------------------------------------
  1274. //
  1275. // Funciton: This function is only called if the device is a modem.
  1276. //
  1277. // 7-9-93 We now open the modem response section when a DCB
  1278. // is created for the first modem. Then we leave it open
  1279. // (while the RASMXS DLL is in memory).
  1280. //
  1281. // Returns: Error values from RasDevOpen.
  1282. //
  1283. //*
  1284. DWORD
  1285. OpenResponseSection (PCHAR szFileName)
  1286. {
  1287. DWORD dRC = SUCCESS ;
  1288. // **** Exclusion Begin ****
  1289. WaitForSingleObject(ResponseSection.Mutex, INFINITE) ;
  1290. if (ResponseSection.UseCount == 0)
  1291. dRC = RasDevOpen(szFileName,
  1292. RESPONSES_SECTION_NAME,
  1293. &ResponseSection.Handle) ;
  1294. if (dRC == SUCCESS)
  1295. ResponseSection.UseCount = 1 ; //This used to be an increment.
  1296. // *** Exclusion End ***
  1297. ReleaseMutex(ResponseSection.Mutex);
  1298. return dRC ;
  1299. }
  1300. //* OpenResponseSection ---------------------------------------------------
  1301. //
  1302. // Funciton: This function should never be called.
  1303. //
  1304. // 7-9-93 We now open the modem response section when a DCB
  1305. // is created for the first modem. Then we leave it open
  1306. // (while the RASMXS DLL is in memory).
  1307. //
  1308. // Returns: nothing.
  1309. //
  1310. //*
  1311. /***
  1312. VOID
  1313. CloseResponseSection ()
  1314. {
  1315. // **** Exclusion Begin ****
  1316. WaitForSingleObject(ResponseSection.Mutex, INFINITE) ;
  1317. ResponseSection.UseCount-- ;
  1318. if (ResponseSection.UseCount == 0)
  1319. RasDevClose (ResponseSection.Handle) ;
  1320. // *** Exclusion End ***
  1321. ReleaseMutex(ResponseSection.Mutex);
  1322. }
  1323. ***/
  1324. //* FindOpenDevSection
  1325. //
  1326. //
  1327. // Returns: TRUE if found, FALSE if not.
  1328. //*
  1329. BOOL
  1330. FindOpenDevSection (PTCH lpszFileName, PTCH lpszSectionName, HRASFILE *hFile)
  1331. {
  1332. SavedSections* temp ;
  1333. for (temp = gpSavedSections; temp; temp=temp->Next) {
  1334. if (!_strcmpi (temp->FileName, lpszFileName) &&
  1335. !_strcmpi (temp->SectionName, lpszSectionName) &&
  1336. !temp->InUse) {
  1337. *hFile = temp->hFile ;
  1338. temp->InUse = TRUE ;
  1339. RasDevResetCommand (*hFile) ;
  1340. return TRUE ;
  1341. }
  1342. }
  1343. return FALSE ;
  1344. }
  1345. //*
  1346. //
  1347. //
  1348. //
  1349. //*
  1350. VOID
  1351. AddOpenDevSection (PTCH lpszFileName, PTCH lpszSectionName, HRASFILE hFile)
  1352. {
  1353. SavedSections *temp ;
  1354. GetMem(sizeof(SavedSections), (char **)&temp) ;
  1355. if (temp == NULL)
  1356. return ; // section not saved - no problem
  1357. // strcpy (temp->FileName, lpszFileName) ;
  1358. // strcpy (temp->SectionName, lpszSectionName) ;
  1359. (VOID) StringCchCopyA(temp->FileName, MAX_PATH,
  1360. lpszFileName);
  1361. (VOID) StringCchCopyA(temp->SectionName,
  1362. MAX_DEVICE_NAME + 1,
  1363. lpszSectionName);
  1364. temp->InUse = TRUE ;
  1365. temp->hFile = hFile ;
  1366. if (gpSavedSections)
  1367. temp->Next = gpSavedSections ;
  1368. else
  1369. temp->Next = NULL ;
  1370. gpSavedSections = temp ;
  1371. }
  1372. //*
  1373. //
  1374. //
  1375. //
  1376. //*
  1377. VOID
  1378. CloseOpenDevSection (HRASFILE hFile)
  1379. {
  1380. SavedSections* temp ;
  1381. for (temp = gpSavedSections; temp; temp=temp->Next) {
  1382. if (temp->hFile == hFile) {
  1383. temp->InUse = FALSE ;
  1384. return ;
  1385. }
  1386. }
  1387. }
  1388. //* DbgPrntf --------------------------------------------------------------
  1389. //
  1390. // Funciton: DbgPrntf -- printf to the debugger console
  1391. // Takes printf style arguments.
  1392. // Expects newline characters at the end of the string.
  1393. // Written by BruceK.
  1394. //
  1395. // Returns: nothing
  1396. //
  1397. //*
  1398. #ifdef DEBUG
  1399. #include <stdarg.h>
  1400. #include <stdio.h>
  1401. void DbgPrntf(const char * format, ...) {
  1402. va_list marker;
  1403. char String[512];
  1404. va_start(marker, format);
  1405. vsprintf(String, format, marker);
  1406. OutputDebugString(String);
  1407. }
  1408. #endif //DEBUG
  1409. //* DbgStr ----------------------------------------------------------------
  1410. //
  1411. // Funciton: Writes an unterminated string to the debugger.
  1412. //
  1413. // Returns: nothing
  1414. //
  1415. //*
  1416. #ifdef DEBUG
  1417. void DbgStr(char Str[], DWORD StrLen)
  1418. {
  1419. DWORD i;
  1420. char Char[] = " ";
  1421. for (i=0; i<StrLen; i++)
  1422. {
  1423. Char[0] = Str[i];
  1424. OutputDebugString(Char);
  1425. }
  1426. if (StrLen > 0)
  1427. OutputDebugString("\n");
  1428. }
  1429. #endif //DEBUG
  1430. //* ConPrintf -------------------------------------------------------------
  1431. //
  1432. // Funciton: Writes debug information to the process's console window.
  1433. // Written by StefanS.
  1434. //
  1435. // Returns: nothing
  1436. //
  1437. //*
  1438. #ifdef DBGCON
  1439. VOID
  1440. ConPrintf ( char *Format, ... )
  1441. {
  1442. va_list arglist;
  1443. char OutputBuffer[1024];
  1444. DWORD length;
  1445. va_start( arglist, Format );
  1446. vsprintf( OutputBuffer, Format, arglist );
  1447. va_end( arglist );
  1448. length = strlen( OutputBuffer );
  1449. WriteFile( GetStdHandle(STD_OUTPUT_HANDLE),
  1450. (LPVOID )OutputBuffer,
  1451. length,
  1452. &length,
  1453. NULL );
  1454. }
  1455. #endif //DBGCON