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.

704 lines
16 KiB

  1. /*++
  2. Copyright (C) 1994-98 Microsft Corporation. All rights reserved.
  3. Module Name:
  4. diag.c
  5. Abstract:
  6. This file contains helper routines to get the callerid/calledid
  7. and connect response.
  8. Author:
  9. Rao salapaka (raos) 23-Feb-1998
  10. Revision History:
  11. --*/
  12. #include <nt.h>
  13. #include <ntrtl.h>
  14. #include <nturtl.h>
  15. #include <windows.h>
  16. #include <tapi.h>
  17. #include <rasman.h>
  18. #include <raserror.h>
  19. #include <mprlog.h>
  20. #include <rtutils.h>
  21. #include <media.h>
  22. #include <device.h>
  23. #include <rasmxs.h>
  24. #include <isdn.h>
  25. #include <stdlib.h>
  26. #include <malloc.h>
  27. #include <string.h>
  28. #include "rastapi.h"
  29. #include "reghelp.h"
  30. #include <unimodem.h>
  31. /*++
  32. Routine Description:
  33. Extract CallerID and CalledID information if
  34. available.
  35. Arguments:
  36. port - The tapi port on which the call was made
  37. / on which the call came in
  38. pLineCallInfo - the LINECALLINFO associated with
  39. this call
  40. pdwRequiredSize - pointer to buffer to receive the
  41. size of buffer required to hold
  42. the callerid and called id info.
  43. pConnectInfo - pointer to the RASTAPI_CONNECT_INFO struct
  44. where the information about the
  45. callerid and called id will be filledin.
  46. If this is not NULL then it is assumed
  47. that the buffer is big enough to store
  48. the callerid and called id iformation.
  49. Return Value:
  50. ERROR_SUCCESS if successful
  51. --*/
  52. DWORD
  53. DwGetIDInformation(
  54. TapiPortControlBlock *port,
  55. LINECALLINFO *pLineCallInfo,
  56. DWORD *pdwRequiredSize,
  57. RASTAPI_CONNECT_INFO *pConnectInfo
  58. )
  59. {
  60. DWORD dwRequiredSize = 0;
  61. DWORD dwErr = ERROR_SUCCESS;
  62. RasTapiTrace("DwGetIDInformation");
  63. #if DBG
  64. RasTapiTrace ("RasTapiCallback: connected on %s",
  65. port->TPCB_Name );
  66. RasTapiTrace("RasTapiCallback: CallerIDFlags=0x%x",
  67. pLineCallInfo->dwCallerIDFlags);
  68. RasTapiTrace("RasTapiCallback: CalledIDFlags=0x%x",
  69. pLineCallInfo->dwCalledIDFlags);
  70. RasTapiTrace("RasTapiCallback: dwNeededSize=%d",
  71. pLineCallInfo->dwNeededSize);
  72. RasTapiTrace("RasTapiCallback: dwUsedSize=%d",
  73. pLineCallInfo->dwUsedSize);
  74. RasTapiTrace("RasTapiCallback: dwCallerIDOffset=%d",
  75. pLineCallInfo->dwCallerIDOffset);
  76. RasTapiTrace("RasTapiCallback: dwCalledIdOffset=%d",
  77. pLineCallInfo->dwCalledIDOffset);
  78. RasTapiTrace("RasTapiCallback: dwCallerIdSize=%d",
  79. pLineCallInfo->dwCallerIDSize);
  80. RasTapiTrace("RasTapiCallback: dwCalledIdSize=%d",
  81. pLineCallInfo->dwCalledIDSize);
  82. RasTapiTrace("RasTapiCallback: dwCallerIdNameSize=%d",
  83. pLineCallInfo->dwCallerIDNameSize);
  84. RasTapiTrace("RasTapiCallback: dwCallerIdNameOffset=%d",
  85. pLineCallInfo->dwCallerIDNameOffset);
  86. #endif
  87. //
  88. // Find the size of the buffer to allocate
  89. //
  90. if(pLineCallInfo->dwCallerIDFlags & LINECALLPARTYID_ADDRESS)
  91. {
  92. dwRequiredSize += pLineCallInfo->dwCallerIDSize;
  93. }
  94. if(pLineCallInfo->dwCalledIDFlags & LINECALLPARTYID_ADDRESS)
  95. {
  96. dwRequiredSize += pLineCallInfo->dwCalledIDSize;
  97. }
  98. if( (NULL == pConnectInfo)
  99. || (0 == dwRequiredSize))
  100. {
  101. goto done;
  102. }
  103. //
  104. // If pConnectInfo is != NULL it is assumed
  105. // that the buffer is large enough to put
  106. // the CALLER/CALLED ID information in it.
  107. //
  108. if( ( pLineCallInfo->dwCallerIDFlags
  109. & LINECALLPARTYID_ADDRESS )
  110. && pLineCallInfo->dwCallerIDSize)
  111. {
  112. //
  113. // Copy the caller id information
  114. //
  115. pConnectInfo->dwCallerIdSize =
  116. pLineCallInfo->dwCallerIDSize;
  117. pConnectInfo->dwCallerIdOffset =
  118. FIELD_OFFSET(RASTAPI_CONNECT_INFO, abdata);
  119. memcpy( pConnectInfo->abdata,
  120. (PBYTE) ((PBYTE) pLineCallInfo
  121. + pLineCallInfo->dwCallerIDOffset),
  122. pLineCallInfo->dwCallerIDSize);
  123. }
  124. else
  125. {
  126. RasTapiTrace("RasTapiCallback: caller id "
  127. "info. not avail");
  128. }
  129. if( ( pLineCallInfo->dwCalledIDFlags
  130. & LINECALLPARTYID_ADDRESS)
  131. && pLineCallInfo->dwCalledIDSize)
  132. {
  133. //
  134. // Copy the called id information
  135. //
  136. pConnectInfo->dwCalledIdSize =
  137. pLineCallInfo->dwCalledIDSize;
  138. pConnectInfo->dwCalledIdOffset =
  139. FIELD_OFFSET(RASTAPI_CONNECT_INFO, abdata)
  140. + pConnectInfo->dwCallerIdSize;
  141. memcpy( (PBYTE)
  142. ((PBYTE) pConnectInfo
  143. + pConnectInfo->dwCalledIdOffset),
  144. (PBYTE) ((PBYTE) pLineCallInfo
  145. + pLineCallInfo->dwCalledIDOffset),
  146. pLineCallInfo->dwCalledIDSize);
  147. }
  148. else
  149. {
  150. RasTapiTrace("RasTapiCallback: called id "
  151. "info. not avail");
  152. }
  153. done:
  154. if(pdwRequiredSize)
  155. {
  156. *pdwRequiredSize = dwRequiredSize;
  157. }
  158. RasTapiTrace("DwGetIDInformation. %d", dwErr);
  159. return dwErr;
  160. }
  161. /*++
  162. Routine Description:
  163. Extract the connect responses from lpLineDiagnostics(see
  164. MODEM_KEYTYPE_AT_COMMAND_RESPONSE,MODEMDIAGKEY_ATRESP_CONNECT)
  165. and copy them in lpBuffer
  166. Arguments:
  167. lpLineDiagnostics - diagnostic structure
  168. lpBuffer - destination buffer (can be NULL), upon
  169. return contains null terminated ASCII
  170. strings
  171. dwBufferSize - size in bytes of the buffer pointed
  172. by lpBuffer
  173. lpdwNeededSize - pointer (can be NULL) to a dword to
  174. receive the needed size
  175. Return Value:
  176. Returns the number of bytes copied into lpBuffer
  177. --*/
  178. DWORD
  179. DwGetConnectResponses(
  180. LINEDIAGNOSTICS *lpLineDiagnostics,
  181. LPBYTE lpBuffer,
  182. DWORD dwBufferSize,
  183. LPDWORD lpdwNeededSize
  184. )
  185. {
  186. DWORD dwBytesCopied;
  187. DWORD dwNeededSize;
  188. LINEDIAGNOSTICS *lpstructDiagnostics;
  189. RasTapiTrace("DwGetConnectresponses");
  190. dwBytesCopied = 0;
  191. dwNeededSize = 0;
  192. lpstructDiagnostics = lpLineDiagnostics;
  193. while (NULL != lpstructDiagnostics)
  194. {
  195. LINEDIAGNOSTICS_PARSEREC *lpParsedDiagnostics;
  196. LINEDIAGNOSTICSOBJECTHEADER *lpParsedHeader;
  197. DWORD dwNumItems;
  198. DWORD dwIndex;
  199. //
  200. // check the signature for modem diagnostics
  201. //
  202. lpParsedHeader = PARSEDDIAGNOSTICS_HDR(lpstructDiagnostics);
  203. if ( (lpstructDiagnostics->hdr.dwSig
  204. != LDSIG_LINEDIAGNOSTICS)
  205. || (lpstructDiagnostics->dwDomainID
  206. != DOMAINID_MODEM)
  207. || !IS_VALID_PARSEDDIAGNOSTICS_HDR(lpParsedHeader))
  208. {
  209. goto NextStructure;
  210. }
  211. //
  212. // get parsed structure info
  213. //
  214. dwNumItems = PARSEDDIAGNOSTICS_NUM_ITEMS(lpParsedHeader);
  215. lpParsedDiagnostics = PARSEDDIAGNOSTICS_DATA(lpstructDiagnostics);
  216. //
  217. // iterate the array of LINEDIAGNOSTICS_PARSERECs
  218. //
  219. for (dwIndex = 0; dwIndex < dwNumItems; dwIndex++)
  220. {
  221. DWORD dwThisLength;
  222. LPSTR lpszThisString;
  223. //
  224. // check is a connect response
  225. //
  226. if ( (lpParsedDiagnostics[dwIndex].dwKeyType !=
  227. MODEM_KEYTYPE_AT_COMMAND_RESPONSE)
  228. || (lpParsedDiagnostics[dwIndex].dwKey !=
  229. MODEMDIAGKEY_ATRESP_CONNECT)
  230. || !(lpParsedDiagnostics[dwIndex].dwFlags &
  231. fPARSEKEYVALUE_ASCIIZ_STRING))
  232. {
  233. continue;
  234. }
  235. //
  236. // get the string, dwValue offset from the beginning
  237. // of lpParsedDiagnostics
  238. //
  239. lpszThisString = (LPSTR) ( (LPBYTE) lpParsedHeader +
  240. lpParsedDiagnostics[dwIndex].dwValue);
  241. dwThisLength = strlen(lpszThisString) + 1;
  242. if (dwThisLength == 1)
  243. {
  244. continue;
  245. }
  246. //
  247. // update needed size
  248. //
  249. dwNeededSize += dwThisLength;
  250. //
  251. // copy to buffer, if large enough
  252. //
  253. if ( NULL != lpBuffer
  254. && dwBytesCopied < dwBufferSize - 1)
  255. {
  256. DWORD dwBytesToCopy;
  257. //
  258. // dwThisLength includes null char, so
  259. // does dwBytesToCopy
  260. //
  261. dwBytesToCopy = min(dwThisLength,
  262. dwBufferSize
  263. - 1
  264. - dwBytesCopied);
  265. if (dwBytesToCopy > 1)
  266. {
  267. memcpy(lpBuffer + dwBytesCopied,
  268. lpszThisString,
  269. dwBytesToCopy - 1);
  270. lpBuffer[dwBytesCopied + dwBytesToCopy - 1] = 0;
  271. dwBytesCopied += dwBytesToCopy;
  272. }
  273. }
  274. }
  275. NextStructure:
  276. if (lpstructDiagnostics->hdr.dwNextObjectOffset != 0)
  277. {
  278. lpstructDiagnostics = (LINEDIAGNOSTICS *)
  279. (((LPBYTE) lpstructDiagnostics) +
  280. lpstructDiagnostics->hdr.dwNextObjectOffset);
  281. }
  282. else
  283. {
  284. lpstructDiagnostics = NULL;
  285. }
  286. }
  287. //
  288. // the final null only if data is not empty
  289. //
  290. if (dwNeededSize > 0)
  291. {
  292. dwNeededSize++;
  293. if ( lpBuffer != NULL
  294. && dwBytesCopied < dwBufferSize)
  295. {
  296. lpBuffer[dwBytesCopied] = 0;
  297. dwBytesCopied++;
  298. }
  299. }
  300. if (lpdwNeededSize != NULL)
  301. {
  302. *lpdwNeededSize = dwNeededSize;
  303. }
  304. RasTapiTrace("DwGetConnectResponses done");
  305. return dwBytesCopied;
  306. }
  307. /*++
  308. Routine Description:
  309. Extract the connect response information
  310. Arguments:
  311. pLineCallInfo - the LINECALLINFO associated with
  312. this call
  313. hCall - handle to call
  314. pdwRequiredSize - This is in/out parameter. As IN it
  315. specifies the size of pBuffer. As
  316. OUT it contains the size required
  317. to store the connect response.
  318. pBuffer - buffer to receive the connect response. This
  319. can be NULL.
  320. Return Value:
  321. ERROR_SUCCESS if successful
  322. --*/
  323. DWORD
  324. DwGetConnectResponseInformation(
  325. LINECALLINFO *pLineCallInfo,
  326. HCALL hCall,
  327. DWORD *pdwRequiredSize,
  328. BYTE *pBuffer
  329. )
  330. {
  331. LONG lr = ERROR_SUCCESS;
  332. BYTE bvar[100];
  333. LPVARSTRING pvar = (LPVARSTRING) bvar;
  334. LINEDIAGNOSTICS *pLineDiagnostics;
  335. DWORD dwConnectResponseSize = 0;
  336. RasTapiTrace("DwGetConnectResponseInformation");
  337. //
  338. // Get the diagnostics information
  339. //
  340. ZeroMemory (pvar, sizeof(*pvar));
  341. pvar->dwTotalSize = sizeof(bvar);
  342. lr = lineGetID(
  343. pLineCallInfo->hLine,
  344. pLineCallInfo->dwAddressID,
  345. hCall,
  346. LINECALLSELECT_CALL,
  347. pvar,
  348. szUMDEVCLASS_TAPI_LINE_DIAGNOSTICS);
  349. if( (LINEERR_STRUCTURETOOSMALL == lr)
  350. || pvar->dwNeededSize > sizeof(bvar))
  351. {
  352. DWORD dwNeededSize = pvar->dwNeededSize;
  353. //
  354. // Allocate the required size
  355. //
  356. pvar = LocalAlloc(
  357. LPTR,
  358. dwNeededSize);
  359. if(NULL == pvar)
  360. {
  361. lr = (LONG) GetLastError();
  362. goto done;
  363. }
  364. ZeroMemory (pvar, sizeof(*pvar));
  365. pvar->dwTotalSize = dwNeededSize;
  366. lr = lineGetID(
  367. pLineCallInfo->hLine,
  368. pLineCallInfo->dwAddressID,
  369. hCall,
  370. LINECALLSELECT_CALL,
  371. pvar,
  372. szUMDEVCLASS_TAPI_LINE_DIAGNOSTICS);
  373. if(ERROR_SUCCESS != lr)
  374. {
  375. goto done;
  376. }
  377. }
  378. else if(ERROR_SUCCESS != lr)
  379. {
  380. goto done;
  381. }
  382. pLineDiagnostics = (LINEDIAGNOSTICS *) ((LPBYTE) pvar
  383. + pvar->dwStringOffset);
  384. (void) DwGetConnectResponses(
  385. pLineDiagnostics,
  386. pBuffer,
  387. *pdwRequiredSize,
  388. &dwConnectResponseSize);
  389. done:
  390. if(bvar != (LPBYTE) pvar)
  391. {
  392. LocalFree(pvar);
  393. }
  394. *pdwRequiredSize = dwConnectResponseSize;
  395. RasTapiTrace("DwGetConnectResponseInformation. 0x%x",
  396. lr);
  397. return (DWORD) lr;
  398. }
  399. /*++
  400. Routine Description:
  401. Extract the connection information. This includes
  402. extracing the caller id / called id information
  403. and the connect response information for modems.
  404. Arguments:
  405. port - pointer to the rastapi port on which the
  406. call came in / was made
  407. hCall - handle to call
  408. pLineCallInfo - pointer to the LINECALLINFO structure
  409. associated with this call.
  410. Return Value:
  411. ERROR_SUCCESS if succcessful
  412. --*/
  413. DWORD
  414. DwGetConnectInfo(
  415. TapiPortControlBlock *port,
  416. HCALL hCall,
  417. LINECALLINFO *pLineCallInfo
  418. )
  419. {
  420. DWORD dwErr = ERROR_SUCCESS;
  421. DWORD dwRequiredSize = 0;
  422. DWORD dwConnectResponseSize = 0;
  423. RASTAPI_CONNECT_INFO *pConnectInfo = NULL;
  424. RasTapiTrace("DwGetConnectInfo");
  425. //
  426. // Get the size required to store the
  427. // caller/called id information
  428. //
  429. dwErr = DwGetIDInformation(port,
  430. pLineCallInfo,
  431. &dwRequiredSize,
  432. NULL);
  433. if(ERROR_SUCCESS != dwErr)
  434. {
  435. goto done;
  436. }
  437. RasTapiTrace("SizeRequired for CallID=%d",
  438. dwRequiredSize);
  439. if(0 == _stricmp(port->TPCB_DeviceType, "modem"))
  440. {
  441. //
  442. // Get the size required to store connect
  443. // response if this is a modem
  444. //
  445. dwErr = DwGetConnectResponseInformation(
  446. pLineCallInfo,
  447. hCall,
  448. &dwConnectResponseSize,
  449. NULL);
  450. if(NO_ERROR != dwErr)
  451. {
  452. goto done;
  453. }
  454. RasTapiTrace("SizeRequired for ConnectResponse=%d",
  455. dwConnectResponseSize);
  456. }
  457. if(0 == (dwRequiredSize + dwConnectResponseSize))
  458. {
  459. //
  460. // None of the information is available.
  461. // bail.
  462. //
  463. RasTapiTrace("CallIDSize=ConnectResponseSize=0");
  464. goto done;
  465. }
  466. dwRequiredSize += ( dwConnectResponseSize
  467. + sizeof(RASTAPI_CONNECT_INFO));
  468. //
  469. // Allocate the buffer
  470. //
  471. pConnectInfo = (RASTAPI_CONNECT_INFO *) LocalAlloc(
  472. LPTR,
  473. dwRequiredSize);
  474. if(NULL == pConnectInfo)
  475. {
  476. dwErr = GetLastError();
  477. goto done;
  478. }
  479. //
  480. // Get the actual information
  481. //
  482. dwErr = DwGetIDInformation(
  483. port,
  484. pLineCallInfo,
  485. NULL,
  486. pConnectInfo);
  487. if(NO_ERROR != dwErr)
  488. {
  489. goto done;
  490. }
  491. //
  492. // Get Connect response if its a modem
  493. //
  494. if(0 == _stricmp(port->TPCB_DeviceType, "modem"))
  495. {
  496. pConnectInfo->dwConnectResponseOffset =
  497. FIELD_OFFSET(RASTAPI_CONNECT_INFO, abdata)
  498. + pConnectInfo->dwCallerIdSize
  499. + pConnectInfo->dwCalledIdSize;
  500. pConnectInfo->dwConnectResponseSize =
  501. dwConnectResponseSize;
  502. dwErr = DwGetConnectResponseInformation(
  503. pLineCallInfo,
  504. hCall,
  505. &dwConnectResponseSize,
  506. (PBYTE) ((PBYTE) pConnectInfo
  507. + pConnectInfo->dwConnectResponseOffset));
  508. if(ERROR_SUCCESS != dwErr)
  509. {
  510. goto done;
  511. }
  512. }
  513. port->TPCB_pConnectInfo = pConnectInfo;
  514. done:
  515. if( NO_ERROR != dwErr
  516. && NULL != pConnectInfo)
  517. {
  518. LocalFree(pConnectInfo);
  519. }
  520. RasTapiTrace("DwGetConnectInfo. 0x%x",
  521. dwErr);
  522. return dwErr;
  523. }