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.

733 lines
17 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. //
  93. // Add one byte to allocate for NULL char
  94. //
  95. dwRequiredSize += RASMAN_ALIGN8(pLineCallInfo->dwCallerIDSize + 1);
  96. }
  97. if(pLineCallInfo->dwCalledIDFlags & LINECALLPARTYID_ADDRESS)
  98. {
  99. //
  100. // Add one byte to allocate for NULL char
  101. //
  102. dwRequiredSize += RASMAN_ALIGN8(pLineCallInfo->dwCalledIDSize + 1);
  103. }
  104. if( (NULL == pConnectInfo)
  105. || (0 == dwRequiredSize))
  106. {
  107. goto done;
  108. }
  109. //
  110. // If pConnectInfo is != NULL it is assumed
  111. // that the buffer is large enough to put
  112. // the CALLER/CALLED ID information in it.
  113. //
  114. if( ( pLineCallInfo->dwCallerIDFlags
  115. & LINECALLPARTYID_ADDRESS )
  116. && pLineCallInfo->dwCallerIDSize)
  117. {
  118. //
  119. // Copy the caller id information. Note that abdata
  120. // is already aligned at 8byte boundary
  121. //
  122. pConnectInfo->dwCallerIdSize =
  123. pLineCallInfo->dwCallerIDSize;
  124. pConnectInfo->dwCallerIdOffset =
  125. FIELD_OFFSET(RASTAPI_CONNECT_INFO, abdata);
  126. ZeroMemory(
  127. pConnectInfo->abdata,
  128. pLineCallInfo->dwCallerIDSize + 1);
  129. memcpy( pConnectInfo->abdata,
  130. (PBYTE) ((PBYTE) pLineCallInfo
  131. + pLineCallInfo->dwCallerIDOffset),
  132. pLineCallInfo->dwCallerIDSize);
  133. RasTapiTrace("GetIDInformation: CallerID=%s",
  134. (CHAR *) pConnectInfo->abdata);
  135. //
  136. // for the NULL char
  137. //
  138. pConnectInfo->dwCallerIdSize += 1;
  139. }
  140. else
  141. {
  142. RasTapiTrace("RasTapiCallback: caller id "
  143. "info. not avail");
  144. }
  145. if( ( pLineCallInfo->dwCalledIDFlags
  146. & LINECALLPARTYID_ADDRESS)
  147. && pLineCallInfo->dwCalledIDSize)
  148. {
  149. //
  150. // Copy the called id information
  151. //
  152. pConnectInfo->dwCalledIdSize =
  153. pLineCallInfo->dwCalledIDSize;
  154. pConnectInfo->dwCalledIdOffset =
  155. FIELD_OFFSET(RASTAPI_CONNECT_INFO, abdata)
  156. + RASMAN_ALIGN8(pConnectInfo->dwCallerIdSize);
  157. ZeroMemory((PBYTE)
  158. ((PBYTE) pConnectInfo
  159. + pConnectInfo->dwCalledIdOffset),
  160. pLineCallInfo->dwCalledIDSize + 1);
  161. memcpy( (PBYTE)
  162. ((PBYTE) pConnectInfo
  163. + pConnectInfo->dwCalledIdOffset),
  164. (PBYTE) ((PBYTE) pLineCallInfo
  165. + pLineCallInfo->dwCalledIDOffset),
  166. pLineCallInfo->dwCalledIDSize);
  167. //
  168. // For the calledID
  169. //
  170. pConnectInfo->dwCalledIdSize += 1;
  171. }
  172. else
  173. {
  174. RasTapiTrace("RasTapiCallback: called id "
  175. "info. not avail");
  176. }
  177. done:
  178. if(pdwRequiredSize)
  179. {
  180. *pdwRequiredSize = dwRequiredSize;
  181. }
  182. RasTapiTrace("DwGetIDInformation. %d", dwErr);
  183. return dwErr;
  184. }
  185. /*++
  186. Routine Description:
  187. Extract the connect responses from lpLineDiagnostics(see
  188. MODEM_KEYTYPE_AT_COMMAND_RESPONSE,MODEMDIAGKEY_ATRESP_CONNECT)
  189. and copy them in lpBuffer
  190. Arguments:
  191. lpLineDiagnostics - diagnostic structure
  192. lpBuffer - destination buffer (can be NULL), upon
  193. return contains null terminated ASCII
  194. strings
  195. dwBufferSize - size in bytes of the buffer pointed
  196. by lpBuffer
  197. lpdwNeededSize - pointer (can be NULL) to a dword to
  198. receive the needed size
  199. Return Value:
  200. Returns the number of bytes copied into lpBuffer
  201. --*/
  202. DWORD
  203. DwGetConnectResponses(
  204. LINEDIAGNOSTICS *lpLineDiagnostics,
  205. LPBYTE lpBuffer,
  206. DWORD dwBufferSize,
  207. LPDWORD lpdwNeededSize
  208. )
  209. {
  210. DWORD dwBytesCopied;
  211. DWORD dwNeededSize;
  212. LINEDIAGNOSTICS *lpstructDiagnostics;
  213. RasTapiTrace("DwGetConnectresponses");
  214. dwBytesCopied = 0;
  215. dwNeededSize = 0;
  216. lpstructDiagnostics = lpLineDiagnostics;
  217. while (NULL != lpstructDiagnostics)
  218. {
  219. LINEDIAGNOSTICS_PARSEREC *lpParsedDiagnostics;
  220. LINEDIAGNOSTICSOBJECTHEADER *lpParsedHeader;
  221. DWORD dwNumItems;
  222. DWORD dwIndex;
  223. //
  224. // check the signature for modem diagnostics
  225. //
  226. lpParsedHeader = PARSEDDIAGNOSTICS_HDR(lpstructDiagnostics);
  227. if ( (lpstructDiagnostics->hdr.dwSig
  228. != LDSIG_LINEDIAGNOSTICS)
  229. || (lpstructDiagnostics->dwDomainID
  230. != DOMAINID_MODEM)
  231. || !IS_VALID_PARSEDDIAGNOSTICS_HDR(lpParsedHeader))
  232. {
  233. goto NextStructure;
  234. }
  235. //
  236. // get parsed structure info
  237. //
  238. dwNumItems = PARSEDDIAGNOSTICS_NUM_ITEMS(lpParsedHeader);
  239. lpParsedDiagnostics = PARSEDDIAGNOSTICS_DATA(lpstructDiagnostics);
  240. //
  241. // iterate the array of LINEDIAGNOSTICS_PARSERECs
  242. //
  243. for (dwIndex = 0; dwIndex < dwNumItems; dwIndex++)
  244. {
  245. DWORD dwThisLength;
  246. LPSTR lpszThisString;
  247. //
  248. // check is a connect response
  249. //
  250. if ( (lpParsedDiagnostics[dwIndex].dwKeyType !=
  251. MODEM_KEYTYPE_AT_COMMAND_RESPONSE)
  252. || (lpParsedDiagnostics[dwIndex].dwKey !=
  253. MODEMDIAGKEY_ATRESP_CONNECT)
  254. || !(lpParsedDiagnostics[dwIndex].dwFlags &
  255. fPARSEKEYVALUE_ASCIIZ_STRING))
  256. {
  257. continue;
  258. }
  259. //
  260. // get the string, dwValue offset from the beginning
  261. // of lpParsedDiagnostics
  262. //
  263. lpszThisString = (LPSTR) ( (LPBYTE) lpParsedHeader +
  264. lpParsedDiagnostics[dwIndex].dwValue);
  265. dwThisLength = strlen(lpszThisString) + 1;
  266. if (dwThisLength == 1)
  267. {
  268. continue;
  269. }
  270. //
  271. // update needed size
  272. //
  273. dwNeededSize += dwThisLength;
  274. //
  275. // copy to buffer, if large enough
  276. //
  277. if ( NULL != lpBuffer
  278. && dwBytesCopied < dwBufferSize - 1)
  279. {
  280. DWORD dwBytesToCopy;
  281. //
  282. // dwThisLength includes null char, so
  283. // does dwBytesToCopy
  284. //
  285. dwBytesToCopy = min(dwThisLength,
  286. dwBufferSize
  287. - 1
  288. - dwBytesCopied);
  289. if (dwBytesToCopy > 1)
  290. {
  291. memcpy(lpBuffer + dwBytesCopied,
  292. lpszThisString,
  293. dwBytesToCopy - 1);
  294. lpBuffer[dwBytesCopied + dwBytesToCopy - 1] = 0;
  295. dwBytesCopied += dwBytesToCopy;
  296. }
  297. }
  298. }
  299. NextStructure:
  300. if (lpstructDiagnostics->hdr.dwNextObjectOffset != 0)
  301. {
  302. lpstructDiagnostics = (LINEDIAGNOSTICS *)
  303. (((LPBYTE) lpstructDiagnostics) +
  304. lpstructDiagnostics->hdr.dwNextObjectOffset);
  305. }
  306. else
  307. {
  308. lpstructDiagnostics = NULL;
  309. }
  310. }
  311. //
  312. // the final null only if data is not empty
  313. //
  314. if (dwNeededSize > 0)
  315. {
  316. dwNeededSize++;
  317. if ( lpBuffer != NULL
  318. && dwBytesCopied < dwBufferSize)
  319. {
  320. lpBuffer[dwBytesCopied] = 0;
  321. dwBytesCopied++;
  322. }
  323. }
  324. if (lpdwNeededSize != NULL)
  325. {
  326. *lpdwNeededSize = dwNeededSize;
  327. }
  328. RasTapiTrace("DwGetConnectResponses done");
  329. return dwBytesCopied;
  330. }
  331. /*++
  332. Routine Description:
  333. Extract the connect response information
  334. Arguments:
  335. pLineCallInfo - the LINECALLINFO associated with
  336. this call
  337. hCall - handle to call
  338. pdwRequiredSize - This is in/out parameter. As IN it
  339. specifies the size of pBuffer. As
  340. OUT it contains the size required
  341. to store the connect response.
  342. pBuffer - buffer to receive the connect response. This
  343. can be NULL.
  344. Return Value:
  345. ERROR_SUCCESS if successful
  346. --*/
  347. DWORD
  348. DwGetConnectResponseInformation(
  349. LINECALLINFO *pLineCallInfo,
  350. HCALL hCall,
  351. DWORD *pdwRequiredSize,
  352. BYTE *pBuffer
  353. )
  354. {
  355. LONG lr = ERROR_SUCCESS;
  356. BYTE bvar[100];
  357. LPVARSTRING pvar = (LPVARSTRING) bvar;
  358. LINEDIAGNOSTICS *pLineDiagnostics;
  359. DWORD dwConnectResponseSize = 0;
  360. RasTapiTrace("DwGetConnectResponseInformation");
  361. //
  362. // Get the diagnostics information
  363. //
  364. ZeroMemory (pvar, sizeof(*pvar));
  365. pvar->dwTotalSize = sizeof(bvar);
  366. lr = lineGetID(
  367. pLineCallInfo->hLine,
  368. pLineCallInfo->dwAddressID,
  369. hCall,
  370. LINECALLSELECT_CALL,
  371. pvar,
  372. szUMDEVCLASS_TAPI_LINE_DIAGNOSTICS);
  373. if( (LINEERR_STRUCTURETOOSMALL == lr)
  374. || pvar->dwNeededSize > sizeof(bvar))
  375. {
  376. DWORD dwNeededSize = pvar->dwNeededSize;
  377. //
  378. // Allocate the required size
  379. //
  380. pvar = LocalAlloc(
  381. LPTR,
  382. dwNeededSize);
  383. if(NULL == pvar)
  384. {
  385. lr = (LONG) GetLastError();
  386. goto done;
  387. }
  388. ZeroMemory (pvar, sizeof(*pvar));
  389. pvar->dwTotalSize = dwNeededSize;
  390. lr = lineGetID(
  391. pLineCallInfo->hLine,
  392. pLineCallInfo->dwAddressID,
  393. hCall,
  394. LINECALLSELECT_CALL,
  395. pvar,
  396. szUMDEVCLASS_TAPI_LINE_DIAGNOSTICS);
  397. if(ERROR_SUCCESS != lr)
  398. {
  399. goto done;
  400. }
  401. }
  402. else if(ERROR_SUCCESS != lr)
  403. {
  404. goto done;
  405. }
  406. pLineDiagnostics = (LINEDIAGNOSTICS *) ((LPBYTE) pvar
  407. + pvar->dwStringOffset);
  408. (void) DwGetConnectResponses(
  409. pLineDiagnostics,
  410. pBuffer,
  411. *pdwRequiredSize,
  412. &dwConnectResponseSize);
  413. done:
  414. if(bvar != (LPBYTE) pvar)
  415. {
  416. LocalFree(pvar);
  417. }
  418. *pdwRequiredSize = dwConnectResponseSize;
  419. RasTapiTrace("DwGetConnectResponseInformation. 0x%x",
  420. lr);
  421. return (DWORD) lr;
  422. }
  423. /*++
  424. Routine Description:
  425. Extract the connection information. This includes
  426. extracing the caller id / called id information
  427. and the connect response information for modems.
  428. Arguments:
  429. port - pointer to the rastapi port on which the
  430. call came in / was made
  431. hCall - handle to call
  432. pLineCallInfo - pointer to the LINECALLINFO structure
  433. associated with this call.
  434. Return Value:
  435. ERROR_SUCCESS if succcessful
  436. --*/
  437. DWORD
  438. DwGetConnectInfo(
  439. TapiPortControlBlock *port,
  440. HCALL hCall,
  441. LINECALLINFO *pLineCallInfo
  442. )
  443. {
  444. DWORD dwErr = ERROR_SUCCESS;
  445. DWORD dwRequiredSize = 0;
  446. DWORD dwConnectResponseSize = 0;
  447. RASTAPI_CONNECT_INFO *pConnectInfo = NULL;
  448. RasTapiTrace("DwGetConnectInfo");
  449. //
  450. // Get the size required to store the
  451. // caller/called id information
  452. //
  453. dwErr = DwGetIDInformation(port,
  454. pLineCallInfo,
  455. &dwRequiredSize,
  456. NULL);
  457. if(ERROR_SUCCESS != dwErr)
  458. {
  459. goto done;
  460. }
  461. RasTapiTrace("SizeRequired for CallID=%d",
  462. dwRequiredSize);
  463. if(0 == _stricmp(port->TPCB_DeviceType, "modem"))
  464. {
  465. //
  466. // Get the size required to store connect
  467. // response if this is a modem
  468. //
  469. dwErr = DwGetConnectResponseInformation(
  470. pLineCallInfo,
  471. hCall,
  472. &dwConnectResponseSize,
  473. NULL);
  474. if(NO_ERROR != dwErr)
  475. {
  476. goto done;
  477. }
  478. RasTapiTrace("SizeRequired for ConnectResponse=%d",
  479. dwConnectResponseSize);
  480. }
  481. if(0 == (dwRequiredSize + dwConnectResponseSize))
  482. {
  483. //
  484. // None of the information is available.
  485. // bail.
  486. //
  487. RasTapiTrace("CallIDSize=ConnectResponseSize=0");
  488. goto done;
  489. }
  490. dwRequiredSize += ( RASMAN_ALIGN8(dwConnectResponseSize)
  491. + sizeof(RASTAPI_CONNECT_INFO));
  492. //
  493. // Allocate the buffer
  494. //
  495. pConnectInfo = (RASTAPI_CONNECT_INFO *) LocalAlloc(
  496. LPTR,
  497. dwRequiredSize);
  498. if(NULL == pConnectInfo)
  499. {
  500. dwErr = GetLastError();
  501. goto done;
  502. }
  503. //
  504. // Get the actual information
  505. //
  506. dwErr = DwGetIDInformation(
  507. port,
  508. pLineCallInfo,
  509. NULL,
  510. pConnectInfo);
  511. if(NO_ERROR != dwErr)
  512. {
  513. goto done;
  514. }
  515. //
  516. // Get Connect response if its a modem
  517. //
  518. if(0 == _stricmp(port->TPCB_DeviceType, "modem"))
  519. {
  520. pConnectInfo->dwConnectResponseOffset =
  521. FIELD_OFFSET(RASTAPI_CONNECT_INFO, abdata)
  522. + RASMAN_ALIGN8(pConnectInfo->dwCallerIdSize)
  523. + RASMAN_ALIGN8(pConnectInfo->dwCalledIdSize);
  524. pConnectInfo->dwConnectResponseSize =
  525. dwConnectResponseSize;
  526. dwErr = DwGetConnectResponseInformation(
  527. pLineCallInfo,
  528. hCall,
  529. &dwConnectResponseSize,
  530. (PBYTE) ((PBYTE) pConnectInfo
  531. + pConnectInfo->dwConnectResponseOffset));
  532. if(ERROR_SUCCESS != dwErr)
  533. {
  534. goto done;
  535. }
  536. }
  537. port->TPCB_pConnectInfo = pConnectInfo;
  538. done:
  539. if( NO_ERROR != dwErr
  540. && NULL != pConnectInfo)
  541. {
  542. LocalFree(pConnectInfo);
  543. }
  544. RasTapiTrace("DwGetConnectInfo. 0x%x",
  545. dwErr);
  546. return dwErr;
  547. }