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.

1629 lines
55 KiB

  1. /*****************************************************************************
  2. *
  3. * Copyright (c) 1998-1999 Microsoft Corporation
  4. *
  5. * TAPI.C - TAPI handling functions
  6. *
  7. * Author: Stan Adermann (stana)
  8. *
  9. * Created: 9/17/1998
  10. *
  11. *****************************************************************************/
  12. #include "raspptp.h"
  13. #include "tapi.tmh"
  14. NDIS_STATUS
  15. TapiAnswer(
  16. IN PPPTP_ADAPTER pAdapter,
  17. IN PNDIS_TAPI_ANSWER pRequest
  18. )
  19. {
  20. PCALL_SESSION pCall = NULL;
  21. PCONTROL_TUNNEL pCtl;
  22. BOOLEAN LockHeld = FALSE;
  23. NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
  24. DEBUGMSG(DBG_FUNC, (DTEXT("+TapiAnswer\n")));
  25. if ( pRequest == NULL || pAdapter == NULL )
  26. {
  27. gCounters.ulAnswerNullRequest++;
  28. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiAnswer NDIS_STATUS_TAPI_INVALPARAM\n")));
  29. WPLOG(LL_A, LM_TAPI, ("-NDIS_STATUS_TAPI_INVALPARAM"));
  30. return NDIS_STATUS_TAPI_INVALPARAM;
  31. }
  32. pCall = CallGetCall(pAdapter, pRequest->hdCall);
  33. // Verify the ID
  34. if (!pCall)
  35. {
  36. gCounters.ulAnswerNullCall++;
  37. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiAnswer NDIS_STATUS_TAPI_INVALCALLHANDLE\n")));
  38. WPLOG(LL_A, LM_TAPI, ("-NDIS_STATUS_TAPI_INVALCALLHANDLE"));
  39. return NDIS_STATUS_TAPI_INVALCALLHANDLE;
  40. }
  41. DBGTRACE('A');
  42. WPLOG(LL_I, LM_TAPI, ("Answer Cid %d", (ULONG)pCall->DeviceId));
  43. NdisAcquireSpinLock(&pCall->Lock);
  44. LockHeld = TRUE;
  45. pCtl = pCall->pCtl;
  46. if (!pCtl)
  47. {
  48. DBGTRACE('t');
  49. gCounters.ulAnswerNullControl++;
  50. DEBUGMSG(DBG_WARN, (DTEXT("TapiAnswer: No control tunnel Cid %d\n"), pCall->DeviceId));
  51. WPLOG(LL_A, LM_TAPI, ("No control tunnel Cid %d", (ULONG)pCall->DeviceId));
  52. Status = NDIS_STATUS_FAILURE;
  53. }
  54. else if (pCall->State==STATE_CALL_OFFERING)
  55. {
  56. USHORT NewCallId;
  57. PPTP_CALL_OUT_REPLY_PACKET *pReply = CtlAllocPacket(pCtl, CALL_OUT_REPLY);
  58. CallAssignSerialNumber(pCall);
  59. if(PptpClientSide)
  60. {
  61. NewCallId = (USHORT)((pCall->SerialNumber << CALL_ID_INDEX_BITS) + pCall->DeviceId);
  62. if (pCall->Packet.CallId == NewCallId)
  63. {
  64. // Don't allow a line to have the same CallId twice in a row.
  65. NewCallId += (1<<CALL_ID_INDEX_BITS);
  66. }
  67. }
  68. else
  69. {
  70. NewCallId = (USHORT)pCall->FullDeviceId;
  71. }
  72. pCall->Packet.CallId = NewCallId;
  73. if (!pReply)
  74. {
  75. DBGTRACE('r');
  76. gCounters.ulAnswerNullReply++;
  77. DEBUGMSG(DBG_WARN, (DTEXT("TapiAnswer: Failed to alloc a reply packet Cid %d\n"), pCall->DeviceId));
  78. WPLOG(LL_A, LM_TAPI, ("Failed to alloc a reply packet Cid %d", (ULONG)pCall->DeviceId));
  79. Status = NDIS_STATUS_RESOURCES;
  80. }
  81. else
  82. {
  83. pCall->Close.Checklist &= ~(CALL_CLOSE_DROP|
  84. CALL_CLOSE_DROP_COMPLETE|
  85. CALL_CLOSE_CLEANUP_STATE);
  86. CallSetState(pCall, STATE_CALL_ESTABLISHED, 0, LockHeld);
  87. pCall->Speed = pCtl->Speed;
  88. // pCtl is safe to touch because it can't be released from the call
  89. // without the call spinlock.
  90. NdisReleaseSpinLock(&pCall->Lock);
  91. LockHeld = FALSE;
  92. pReply->PeerCallId = htons(pCall->Remote.CallId);
  93. pReply->CallId = htons(pCall->Packet.CallId);
  94. pReply->ResultCode = RESULT_CALL_OUT_CONNECTED;
  95. pReply->RecvWindowSize = PPTP_RECV_WINDOW;
  96. pReply->ConnectSpeed = pCall->Speed;
  97. pReply->ProcessingDelay = 0;
  98. pReply->PhysicalChannelId = 0;
  99. WPLOG(LL_M, LM_TUNNEL, ("SEND CALL_OUT_REPLY -> %!IPADDR! Cid %d, Pkt-Cid %d, Peer's Cid %d",
  100. pCall->Remote.Address.Address[0].Address[0].in_addr,
  101. (ULONG)pCall->DeviceId, pCall->Packet.CallId, pCall->Remote.CallId));
  102. Status = CtlSend(pCtl, pReply);
  103. if (Status!=NDIS_STATUS_SUCCESS)
  104. {
  105. DBGTRACE('s');
  106. gCounters.ulAnswerCtlSendFail++;
  107. DEBUGMSG(DBG_WARN, (DTEXT("TapiAnswer: Failed to send CALL_OUT_REPLY Cid %d\n"), pCall->DeviceId));
  108. WPLOG(LL_A, LM_TAPI, ("Failed to send CALL_OUT_REPLY Cid %d", (ULONG)pCall->DeviceId));
  109. CallSetState(pCall, STATE_CALL_CLEANUP, LINEDISCONNECTMODE_NORMAL, LockHeld);
  110. CallCleanup(pCall, LockHeld);
  111. }
  112. }
  113. }
  114. else if (pCall->State==STATE_CALL_PAC_OFFERING)
  115. {
  116. USHORT NewCallId;
  117. PPTP_CALL_OUT_REPLY_PACKET *pReply = CtlAllocPacket(pCtl, CALL_IN_REPLY);
  118. CallAssignSerialNumber(pCall);
  119. if(PptpClientSide)
  120. {
  121. NewCallId = (USHORT)((pCall->SerialNumber << CALL_ID_INDEX_BITS) + pCall->DeviceId);
  122. if (pCall->Packet.CallId == NewCallId)
  123. {
  124. // Don't allow a line to have the same CallId twice in a row.
  125. NewCallId += (1<<CALL_ID_INDEX_BITS);
  126. }
  127. }
  128. else
  129. {
  130. NewCallId = (USHORT)pCall->FullDeviceId;
  131. }
  132. pCall->Packet.CallId = NewCallId;
  133. if (!pReply)
  134. {
  135. DBGTRACE('r');
  136. gCounters.ulAnswerNullReply++;
  137. DEBUGMSG(DBG_WARN, (DTEXT("TapiAnswer: Failed to alloc a reply packet Cid %d\n"), pCall->DeviceId));
  138. WPLOG(LL_A, LM_TAPI, ("Failed to alloc a reply packet Cid %d", (ULONG)pCall->DeviceId));
  139. Status = NDIS_STATUS_RESOURCES;
  140. }
  141. else
  142. {
  143. pCall->Close.Checklist &= ~(CALL_CLOSE_DROP|
  144. CALL_CLOSE_DROP_COMPLETE|
  145. CALL_CLOSE_CLEANUP_STATE);
  146. CallSetState(pCall, STATE_CALL_PAC_WAIT, 0, LockHeld);
  147. NdisReleaseSpinLock(&pCall->Lock);
  148. LockHeld = FALSE;
  149. pReply->PeerCallId = htons(pCall->Remote.CallId);
  150. pReply->CallId = htons(pCall->Packet.CallId);
  151. pReply->ResultCode = RESULT_CALL_IN_CONNECTED;
  152. pReply->RecvWindowSize = PPTP_RECV_WINDOW;
  153. pReply->ProcessingDelay = 0;
  154. Status = CtlSend(pCtl, pReply);
  155. if (Status!=NDIS_STATUS_SUCCESS)
  156. {
  157. CallSetState(pCall, STATE_CALL_CLEANUP, LINEDISCONNECTMODE_NORMAL, LockHeld);
  158. CallCleanup(pCall, LockHeld);
  159. }
  160. }
  161. }
  162. else
  163. {
  164. DEBUGMSG(DBG_WARN, (DTEXT("Wrong state for TapiAnswer %d\n"), pCall->State));
  165. WPLOG(LL_A, LM_TAPI, ("Wrong state for TapiAnswer %d", pCall->State));
  166. Status = NDIS_STATUS_FAILURE;
  167. }
  168. if (LockHeld)
  169. {
  170. NdisReleaseSpinLock(&pCall->Lock);
  171. }
  172. DEBUGMSG(DBG_FUNC|DBG_ERR(Status), (DTEXT("-TapiAnswer %08x\n"), Status));
  173. return Status;
  174. }
  175. NDIS_STATUS
  176. TapiClose(
  177. IN PPPTP_ADAPTER pAdapter,
  178. IN PNDIS_TAPI_CLOSE pRequest
  179. )
  180. {
  181. PCALL_SESSION pCall;
  182. NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
  183. DEBUGMSG(DBG_FUNC, (DTEXT("+TapiClose\n")));
  184. WPLOG(LL_I, LM_TAPI, ("enter"));
  185. if ( pRequest == NULL || pAdapter == NULL )
  186. {
  187. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiClose NDIS_STATUS_TAPI_INVALPARAM\n")));
  188. WPLOG(LL_A, LM_TAPI, ("-NDIS_STATUS_TAPI_INVALPARAM"));
  189. return NDIS_STATUS_TAPI_INVALPARAM;
  190. }
  191. if (!CallIsValidCall(pAdapter, TapiLineHandleToId(pRequest->hdLine)))
  192. {
  193. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiClose NDIS_STATUS_TAPI_INVALLINEHANDLE\n")));
  194. WPLOG(LL_A, LM_TAPI, ("-NDIS_STATUS_TAPI_INVALLINEHANDLE"));
  195. return NDIS_STATUS_TAPI_INVALLINEHANDLE;
  196. }
  197. NdisAcquireSpinLock(&pAdapter->Lock);
  198. pAdapter->Tapi.Open = FALSE;
  199. NdisReleaseSpinLock(&pAdapter->Lock);
  200. if (pAdapter->hCtdiListen)
  201. {
  202. // We have to pend this request until the listen endpoint is closed
  203. CtdiSetRequestPending(pAdapter->hCtdiListen);
  204. CtdiClose(pAdapter->hCtdiListen);
  205. pAdapter->hCtdiListen = NULL;
  206. Status = NDIS_STATUS_PENDING;
  207. }
  208. DEBUGMSG(DBG_FUNC, (DTEXT("-TapiClose\n")));
  209. WPLOG(LL_I, LM_TAPI, ("exit"));
  210. return Status;
  211. }
  212. NDIS_STATUS
  213. TapiCloseCall(
  214. IN PPPTP_ADAPTER pAdapter,
  215. IN PNDIS_TAPI_CLOSE_CALL pRequest
  216. )
  217. {
  218. PCALL_SESSION pCall;
  219. DEBUGMSG(DBG_FUNC, (DTEXT("+TapiCloseCall\n")));
  220. if ( pRequest == NULL || pAdapter == NULL )
  221. {
  222. gCounters.ulCloseCallNullRequest++;
  223. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiCloseCall NDIS_STATUS_TAPI_INVALPARAM\n")));
  224. WPLOG(LL_A, LM_TAPI, ("-NDIS_STATUS_TAPI_INVALPARAM"));
  225. return NDIS_STATUS_TAPI_INVALPARAM;
  226. }
  227. // Verify the ID
  228. pCall = CallGetCall(pAdapter, pRequest->hdCall);
  229. if (!pCall)
  230. {
  231. gCounters.ulCloseCallNullCall++;
  232. DEBUGMSG(DBG_FUNC|DBG_ERROR, (DTEXT("-TapiCloseCall NDIS_STATUS_TAPI_INVALCALLHANDLE\n")));
  233. WPLOG(LL_A, LM_TAPI, ("-NDIS_STATUS_TAPI_INVALCALLHANDLE"));
  234. return NDIS_STATUS_TAPI_INVALLINEHANDLE;
  235. }
  236. DBGTRACE('C');
  237. WPLOG(LL_M, LM_TAPI, ("Cid %d", (ULONG)pCall->DeviceId));
  238. NdisAcquireSpinLock(&pCall->Lock);
  239. pCall->Close.Checklist |= CALL_CLOSE_CLOSE_CALL;
  240. pCall->hTapiCall = 0;
  241. CallCleanup(pCall, LOCKED);
  242. NdisReleaseSpinLock(&pCall->Lock);
  243. DEBUGMSG(DBG_FUNC, (DTEXT("-TapiCloseCall\n")));
  244. return NDIS_STATUS_SUCCESS;
  245. }
  246. NDIS_STATUS
  247. TapiDrop(
  248. IN PPPTP_ADAPTER pAdapter,
  249. IN PNDIS_TAPI_DROP pRequest
  250. )
  251. {
  252. PCALL_SESSION pCall;
  253. PCONTROL_TUNNEL pCtl;
  254. NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
  255. BOOLEAN CleanupNow = FALSE;
  256. DEBUGMSG(DBG_FUNC, (DTEXT("+TapiDrop\n")));
  257. if ( pRequest == NULL || pAdapter == NULL )
  258. {
  259. gCounters.ulDropNullRequest++;
  260. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiDrop NDIS_STATUS_TAPI_INVALPARAM\n")));
  261. WPLOG(LL_A, LM_TAPI, ("-NDIS_STATUS_TAPI_INVALPARAM"));
  262. return NDIS_STATUS_TAPI_INVALPARAM;
  263. }
  264. // Verify the ID
  265. pCall = CallGetCall(pAdapter, pRequest->hdCall);
  266. if (!pCall)
  267. {
  268. gCounters.ulDropNullCall++;
  269. DEBUGMSG(DBG_FUNC|DBG_ERROR, (DTEXT("-TapiDrop NDIS_STATUS_TAPI_INVALCALLHANDLE\n")));
  270. WPLOG(LL_A, LM_TAPI, ("-NDIS_STATUS_TAPI_INVALCALLHANDLE"));
  271. return NDIS_STATUS_TAPI_INVALCALLHANDLE;
  272. }
  273. DBGTRACE('D');
  274. WPLOG(LL_M, LM_TAPI, ("Drop pCall %p, Cid %d, pCtl %p",
  275. pCall, (ULONG)pCall->DeviceId, pCall->pCtl));
  276. NdisAcquireSpinLock(&pCall->Lock);
  277. //ASSERT(!(pCall->Close.Checklist&CALL_CLOSE_DROP));
  278. pCtl = pCall->pCtl;
  279. if (!pCtl)
  280. {
  281. DBGTRACE('t');
  282. gCounters.ulDropNullControl++;
  283. DEBUGMSG(DBG_WARN, (DTEXT("TapiDrop: No control tunnel Cid %d\n"), pCall->DeviceId));
  284. WPLOG(LL_I, LM_TAPI, ("No control tunnel Cid %d", (ULONG)pCall->DeviceId));
  285. Status = NDIS_STATUS_FAILURE;
  286. }
  287. else if (pCall->State==STATE_CALL_ESTABLISHED)
  288. {
  289. PPPTP_CALL_CLEAR_REQUEST_PACKET pPacket = CtlAllocPacket(pCtl, CALL_CLEAR_REQUEST);
  290. if (!pPacket)
  291. {
  292. DBGTRACE('p');
  293. gCounters.ulDropNullPacket++;
  294. DEBUGMSG(DBG_WARN, (DTEXT("TapiDrop: Failed to alloc CALL_CLEAR_REQUEST Cid %d\n"), pCall->DeviceId));
  295. WPLOG(LL_A, LM_TAPI, ("Failed to alloc CALL_CLEAR_REQUEST Cid %d", (ULONG)pCall->DeviceId));
  296. Status = NDIS_STATUS_RESOURCES;
  297. }
  298. else
  299. {
  300. CallSetState(pCall, STATE_CALL_WAIT_DISCONNECT, 0, LOCKED);
  301. pPacket->CallId = htons(pCall->Packet.CallId);
  302. NdisReleaseSpinLock(&pCall->Lock);
  303. WPLOG(LL_M, LM_TUNNEL, ("SEND CALL_CLEAR_REQUEST -> %!IPADDR! pCall %p, Cid %d, Pkt-Cid %d",
  304. pCtl->Remote.Address.Address[0].Address[0].in_addr,
  305. pCall, (ULONG)pCall->DeviceId, pCall->Packet.CallId));
  306. Status = CtlSend(pCtl, pPacket);
  307. if (Status==NDIS_STATUS_SUCCESS)
  308. {
  309. Status = NDIS_STATUS_PENDING;
  310. }
  311. else
  312. {
  313. DBGTRACE('s');
  314. gCounters.ulDropCtlSendFail++;
  315. DEBUGMSG(DBG_WARN, (DTEXT("TapiDrop: Failed to send CALL_CLEAR_REQUEST Cid %d\n"), pCall->DeviceId));
  316. WPLOG(LL_A, LM_TAPI, ("Failed to send CALL_CLEAR_REQUEST Cid %d", (ULONG)pCall->DeviceId));
  317. }
  318. if (Status==NDIS_STATUS_PENDING)
  319. {
  320. NdisMSetTimer(&pCall->Close.Timer, PPTP_CLOSE_TIMEOUT);
  321. }
  322. NdisAcquireSpinLock(&pCall->Lock);
  323. }
  324. }
  325. else if (pCall->State!=STATE_CALL_CLEANUP)
  326. {
  327. CallSetState(pCall, STATE_CALL_CLEANUP, 0, LOCKED);
  328. CleanupNow = TRUE;
  329. }
  330. pCall->Close.Checklist |= CALL_CLOSE_DROP;
  331. if (Status==NDIS_STATUS_PENDING)
  332. {
  333. pCall->Close.Checklist &= ~CALL_CLOSE_DROP_COMPLETE;
  334. }
  335. else
  336. {
  337. pCall->Close.Checklist |= CALL_CLOSE_DROP_COMPLETE;
  338. }
  339. if (CleanupNow)
  340. {
  341. CallCleanup(pCall, LOCKED);
  342. }
  343. NdisReleaseSpinLock(&pCall->Lock);
  344. DEBUGMSG(DBG_FUNC|DBG_ERR(Status), (DTEXT("-TapiDrop %08x\n"), Status));
  345. return Status;
  346. }
  347. NDIS_STATUS
  348. TapiGetAddressCaps(
  349. IN PPPTP_ADAPTER pAdapter,
  350. IN OUT PNDIS_TAPI_GET_ADDRESS_CAPS pRequest
  351. )
  352. {
  353. BOOLEAN ValidCall;
  354. CHAR LineAddress[TAPI_MAX_LINE_ADDRESS_LENGTH];
  355. DEBUGMSG(DBG_FUNC, (DTEXT("+TapiGetAddressCaps\n")));
  356. if ( pRequest == NULL || pAdapter == NULL )
  357. {
  358. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiGetAddressCaps NDIS_STATUS_TAPI_INVALPARAM\n")));
  359. WPLOG(LL_A, LM_TAPI, ("-NDIS_STATUS_TAPI_INVALPARAM"));
  360. return NDIS_STATUS_TAPI_INVALPARAM;
  361. }
  362. ValidCall = CallIsValidCall(pAdapter, pRequest->ulDeviceID);
  363. if (!ValidCall)
  364. {
  365. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiGetAddressCaps NDIS_STATUS_TAPI_NODRIVER\n")));
  366. WPLOG(LL_A, LM_TAPI, ("-NDIS_STATUS_TAPI_NODRIVER"));
  367. return NDIS_STATUS_TAPI_NODRIVER;
  368. }
  369. if (pRequest->ulAddressID >= TAPI_ADDR_PER_LINE)
  370. {
  371. DEBUGMSG(DBG_FUNC|DBG_ERROR, (DTEXT("-TapiGetAddressCaps NDIS_STATUS_TAPI_INVALADDRESSID\n")));
  372. WPLOG(LL_A, LM_TAPI, ("-NDIS_STATUS_TAPI_INVALADDRESSID"));
  373. return NDIS_STATUS_TAPI_INVALADDRESSID;
  374. }
  375. if (pRequest->ulExtVersion!=0 &&
  376. pRequest->ulExtVersion!=TAPI_EXT_VERSION)
  377. {
  378. DEBUGMSG(DBG_FUNC|DBG_ERROR, (DTEXT("-TapiGetAddressCaps NDIS_STATUS_TAPI_INCOMPATIBLEEXTVERSION\n")));
  379. WPLOG(LL_A, LM_TAPI, ("-NDIS_STATUS_TAPI_INCOMPATIBLEEXTVERSION"));
  380. return NDIS_STATUS_TAPI_INCOMPATIBLEEXTVERSION;
  381. }
  382. pRequest->LineAddressCaps.ulDialToneModes = LINEDIALTONEMODE_NORMAL;
  383. pRequest->LineAddressCaps.ulSpecialInfo = LINESPECIALINFO_UNAVAIL;
  384. pRequest->LineAddressCaps.ulDisconnectModes = LINEDISCONNECTMODE_NORMAL |
  385. LINEDISCONNECTMODE_UNKNOWN |
  386. LINEDISCONNECTMODE_BUSY |
  387. LINEDISCONNECTMODE_NOANSWER;
  388. pRequest->LineAddressCaps.ulMaxNumActiveCalls = pAdapter->Info.Endpoints;
  389. pRequest->LineAddressCaps.ulMaxNumTransConf = 1;
  390. pRequest->LineAddressCaps.ulAddrCapFlags = LINEADDRCAPFLAGS_DIALED;
  391. pRequest->LineAddressCaps.ulCallFeatures = LINECALLFEATURE_ACCEPT |
  392. LINECALLFEATURE_ANSWER |
  393. LINECALLFEATURE_COMPLETECALL |
  394. LINECALLFEATURE_DIAL |
  395. LINECALLFEATURE_DROP;
  396. pRequest->LineAddressCaps.ulLineDeviceID = pRequest->ulDeviceID;
  397. pRequest->LineAddressCaps.ulAddressSharing = LINEADDRESSSHARING_PRIVATE;
  398. pRequest->LineAddressCaps.ulAddressStates = 0;
  399. // List of all possible call states.
  400. pRequest->LineAddressCaps.ulCallStates = LINECALLSTATE_IDLE |
  401. LINECALLSTATE_OFFERING |
  402. LINECALLSTATE_DIALING |
  403. LINECALLSTATE_PROCEEDING |
  404. LINECALLSTATE_CONNECTED |
  405. LINECALLSTATE_DISCONNECTED;
  406. OsGetTapiLineAddress(DeviceIdToIndex(pAdapter, pRequest->ulDeviceID),
  407. LineAddress,
  408. sizeof(LineAddress));
  409. pRequest->LineAddressCaps.ulNeededSize = sizeof(pRequest->LineAddressCaps) +
  410. strlen(LineAddress) + 1;
  411. if (pRequest->LineAddressCaps.ulTotalSize<pRequest->LineAddressCaps.ulNeededSize)
  412. {
  413. pRequest->LineAddressCaps.ulUsedSize = 0;
  414. DEBUGMSG(DBG_FUNC|DBG_ERROR, (DTEXT("-TapiGetAddressCaps NDIS_STATUS_INVALID_LENGTH\n")));
  415. WPLOG(LL_A, LM_TAPI, ("-NDIS_STATUS_INVALID_LENGTH"));
  416. return NDIS_STATUS_INVALID_LENGTH;
  417. }
  418. pRequest->LineAddressCaps.ulAddressSize = strlen(LineAddress) + 1;
  419. pRequest->LineAddressCaps.ulAddressOffset = sizeof(pRequest->LineAddressCaps);
  420. strcpy((PUCHAR)((&pRequest->LineAddressCaps) + 1), LineAddress);
  421. pRequest->LineAddressCaps.ulUsedSize = pRequest->LineAddressCaps.ulNeededSize;
  422. DEBUGMSG(DBG_FUNC, (DTEXT("-TapiGetAddressCaps\n")));
  423. return NDIS_STATUS_SUCCESS;
  424. }
  425. NDIS_STATUS
  426. TapiGetAddressStatus(
  427. IN PPPTP_ADAPTER pAdapter,
  428. IN OUT PNDIS_TAPI_GET_ADDRESS_STATUS pRequest
  429. )
  430. {
  431. PCALL_SESSION pCall = NULL;
  432. BOOLEAN fReady;
  433. DEBUGMSG(DBG_FUNC, (DTEXT("+TapiGetAddressStatus\n")));
  434. if ( pRequest == NULL || pAdapter == NULL )
  435. {
  436. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiGetAddressStatus NDIS_STATUS_TAPI_INVALPARAM\n")));
  437. WPLOG(LL_A, LM_TAPI, ("-NDIS_STATUS_TAPI_INVALPARAM"));
  438. return NDIS_STATUS_TAPI_INVALPARAM;
  439. }
  440. DEBUGMSG(DBG_TAPI, (DTEXT("TapiGetAddressStatus: hdLine=%Xh, ulAddressID=%d\n"),
  441. pRequest->hdLine, pRequest->ulAddressID));
  442. if (!CallIsValidCall(pAdapter, TapiLineHandleToId(pRequest->hdLine)))
  443. {
  444. DEBUGMSG(DBG_FUNC|DBG_ERROR, (DTEXT("-TapiGetAddressStatus NDIS_STATUS_TAPI_INVALCALLHANDLE\n")));
  445. WPLOG(LL_A, LM_TAPI, ("-NDIS_STATUS_TAPI_INVALCALLHANDLE"));
  446. return NDIS_STATUS_TAPI_INVALCALLHANDLE;
  447. }
  448. if (pRequest->ulAddressID >= TAPI_ADDR_PER_LINE)
  449. {
  450. DEBUGMSG(DBG_FUNC|DBG_ERROR, (DTEXT("-TapiGetAddressStatus NDIS_STATUS_TAPI_INVALADDRESSID\n")));
  451. WPLOG(LL_A, LM_TAPI, ("-NDIS_STATUS_TAPI_INVALADDRESSID"));
  452. return NDIS_STATUS_TAPI_INVALADDRESSID;
  453. }
  454. pRequest->LineAddressStatus.ulNeededSize =
  455. pRequest->LineAddressStatus.ulUsedSize = sizeof(pRequest->LineAddressStatus);
  456. pRequest->LineAddressStatus.ulNumInUse = 1;
  457. pRequest->LineAddressStatus.ulNumActiveCalls = 1;
  458. pRequest->LineAddressStatus.ulAddressFeatures = LINEADDRFEATURE_MAKECALL;
  459. pRequest->LineAddressStatus.ulNumRingsNoAnswer = 999;
  460. DEBUGMSG(DBG_FUNC, (DTEXT("-TapiGetAddressStatus\n")));
  461. return NDIS_STATUS_SUCCESS;
  462. }
  463. NDIS_STATUS
  464. TapiGetCallInfo(
  465. IN PPPTP_ADAPTER pAdapter,
  466. IN OUT PNDIS_TAPI_GET_CALL_INFO pRequest,
  467. IN OUT PULONG pRequiredLength
  468. )
  469. {
  470. PCALL_SESSION pCall;
  471. LINE_CALL_INFO *pLineCallInfo = NULL;
  472. ULONG CallerIdLength;
  473. DEBUGMSG(DBG_FUNC, (DTEXT("+TapiGetCallInfo\n")));
  474. if ( pRequest == NULL || pAdapter == NULL )
  475. {
  476. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiGetCallInfo NDIS_STATUS_TAPI_INVALPARAM\n")));
  477. WPLOG(LL_A, LM_TAPI, ("-NDIS_STATUS_TAPI_INVALPARAM"));
  478. return NDIS_STATUS_TAPI_INVALPARAM;
  479. }
  480. pLineCallInfo = &pRequest->LineCallInfo;
  481. // Verify the ID
  482. pCall = CallGetCall(pAdapter, pRequest->hdCall);
  483. if (!pCall)
  484. {
  485. DEBUGMSG(DBG_FUNC, (DTEXT("-TapiGetCallInfo NDIS_STATUS_TAPI_INVALCALLHANDLE\n")));
  486. WPLOG(LL_A, LM_TAPI, ("-NDIS_STATUS_TAPI_INVALCALLHANDLE"));
  487. return NDIS_STATUS_TAPI_INVALCALLHANDLE;
  488. }
  489. CallerIdLength = strlen(pCall->CallerId);
  490. if( CallerIdLength ){
  491. CallerIdLength += 1; // Add one for null terminator
  492. }
  493. if( pRequiredLength ){
  494. // Note: This returns NDIS struct size not LineCallInfo Size
  495. *pRequiredLength = sizeof(NDIS_TAPI_GET_CALL_INFO) + CallerIdLength;
  496. DEBUGMSG(DBG_FUNC, (DTEXT("-TapiGetCallInfo NDIS_STATUS_SUCCESS - Returning Length Only Len=0x%X\n"), *pRequiredLength));
  497. return NDIS_STATUS_SUCCESS;
  498. }
  499. pLineCallInfo->ulNeededSize = sizeof(pRequest->LineCallInfo) + CallerIdLength;
  500. if( pLineCallInfo->ulTotalSize < sizeof(pRequest->LineCallInfo) ){
  501. pLineCallInfo->ulUsedSize = 0;
  502. DEBUGMSG(DBG_FUNC|DBG_ERROR, (DTEXT("-TapiGetCallInfo NDIS_STATUS_INVALID_LENGTH\n")));
  503. WPLOG(LL_A, LM_TAPI, ("-NDIS_STATUS_INVALID_LENGTH"));
  504. return NDIS_STATUS_INVALID_LENGTH;
  505. }
  506. pLineCallInfo->ulUsedSize = sizeof(pRequest->LineCallInfo);
  507. pLineCallInfo->hLine = (ULONG)pCall->DeviceId;
  508. pLineCallInfo->ulLineDeviceID = (ULONG)pCall->DeviceId;
  509. pLineCallInfo->ulAddressID = TAPI_ADDRESSID;
  510. pLineCallInfo->ulBearerMode = LINEBEARERMODE_DATA;
  511. pLineCallInfo->ulRate = pCall->Speed;
  512. pLineCallInfo->ulMediaMode = pCall->MediaModeMask;
  513. pLineCallInfo->ulCallParamFlags = LINECALLPARAMFLAGS_IDLE;
  514. pLineCallInfo->ulCallStates = CALL_STATES_MASK;
  515. pLineCallInfo->ulCallerIDFlags = LINECALLPARTYID_UNAVAIL;
  516. pLineCallInfo->ulCallerIDSize = 0;
  517. pLineCallInfo->ulCalledIDOffset = 0;
  518. pLineCallInfo->ulCalledIDFlags = LINECALLPARTYID_UNAVAIL;
  519. pLineCallInfo->ulCalledIDSize = 0;
  520. if( CallerIdLength ){
  521. if (pLineCallInfo->ulTotalSize >= pLineCallInfo->ulNeededSize)
  522. {
  523. PUCHAR pCallerId = (PUCHAR)(pLineCallInfo + 1);
  524. strcpy(pCallerId, pCall->CallerId);
  525. if (pCall->Inbound)
  526. {
  527. pLineCallInfo->ulCallerIDFlags = LINECALLPARTYID_ADDRESS;
  528. pLineCallInfo->ulCallerIDSize = CallerIdLength;
  529. pLineCallInfo->ulCallerIDOffset = sizeof(LINE_CALL_INFO);
  530. }
  531. else
  532. {
  533. pLineCallInfo->ulCalledIDFlags = LINECALLPARTYID_ADDRESS;
  534. pLineCallInfo->ulCalledIDSize = CallerIdLength;
  535. pLineCallInfo->ulCalledIDOffset = sizeof(LINE_CALL_INFO);
  536. }
  537. pLineCallInfo->ulUsedSize = pLineCallInfo->ulNeededSize;
  538. }else{
  539. DEBUGMSG(DBG_FUNC|DBG_WARN, (DTEXT("-TapiGetCallInfo NDIS_STATUS_SUCCESS without CallerID string\n")));
  540. WPLOG(LL_I, LM_TAPI, ("-NDIS_STATUS_SUCCESS without CallerID string"));
  541. return NDIS_STATUS_SUCCESS;
  542. }
  543. }
  544. DEBUGMSG(DBG_FUNC, (DTEXT("-TapiGetCallInfo\n")));
  545. return NDIS_STATUS_SUCCESS;
  546. }
  547. NDIS_STATUS
  548. TapiGetCallStatus(
  549. IN PPPTP_ADAPTER pAdapter,
  550. IN OUT PNDIS_TAPI_GET_CALL_STATUS pRequest
  551. )
  552. {
  553. PCALL_SESSION pCall;
  554. DEBUGMSG(DBG_FUNC, (DTEXT("+TapiGetCallStatus\n")));
  555. if ( pRequest == NULL || pAdapter == NULL )
  556. {
  557. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiGetCallStatus NDIS_STATUS_TAPI_INVALPARAM\n")));
  558. WPLOG(LL_A, LM_TAPI, ("-NDIS_STATUS_TAPI_INVALPARAM"));
  559. return NDIS_STATUS_TAPI_INVALPARAM;
  560. }
  561. // Verify the ID
  562. pCall = CallGetCall(pAdapter, pRequest->hdCall);
  563. if (!pCall)
  564. {
  565. DEBUGMSG(DBG_FUNC|DBG_ERROR, (DTEXT("-TapiGetCallStatus NDIS_STATUS_TAPI_INVALCALLHANDLE\n")));
  566. WPLOG(LL_A, LM_TAPI, ("-NDIS_STATUS_TAPI_INVALCALLHANDLE"));
  567. return NDIS_STATUS_TAPI_INVALCALLHANDLE;
  568. }
  569. pRequest->LineCallStatus.ulNeededSize =
  570. pRequest->LineCallStatus.ulUsedSize = sizeof(LINE_CALL_STATUS);
  571. pRequest->LineCallStatus.ulCallFeatures = LINECALLFEATURE_ANSWER | LINECALLFEATURE_DROP;
  572. pRequest->LineCallStatus.ulCallPrivilege = LINECALLPRIVILEGE_OWNER;
  573. pRequest->LineCallStatus.ulCallState = CallGetLineCallState(pCall->State);
  574. DBG_X(DBG_TAPI, pRequest->LineCallStatus.ulCallState);
  575. switch (pRequest->LineCallStatus.ulCallState)
  576. {
  577. case LINECALLSTATE_DIALTONE:
  578. pRequest->LineCallStatus.ulCallStateMode = LINEDIALTONEMODE_NORMAL;
  579. break;
  580. case LINECALLSTATE_BUSY:
  581. pRequest->LineCallStatus.ulCallStateMode = LINEBUSYMODE_STATION;
  582. break;
  583. case LINECALLSTATE_DISCONNECTED:
  584. pRequest->LineCallStatus.ulCallStateMode = LINEDISCONNECTMODE_UNKNOWN;
  585. break;
  586. default:
  587. break;
  588. }
  589. DEBUGMSG(DBG_FUNC, (DTEXT("-TapiGetCallStatus\n")));
  590. return NDIS_STATUS_SUCCESS;
  591. }
  592. NDIS_STATUS
  593. TapiGetDevCaps(
  594. IN PPPTP_ADAPTER pAdapter,
  595. IN OUT PNDIS_TAPI_GET_DEV_CAPS pRequest
  596. )
  597. {
  598. BOOLEAN ValidCall;
  599. NDIS_STATUS Status;
  600. DEBUGMSG(DBG_FUNC, (DTEXT("+TapiGetDevCaps\n")));
  601. if ( pRequest == NULL || pAdapter == NULL )
  602. {
  603. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiGetDevCaps NDIS_STATUS_TAPI_INVALPARAM\n")));
  604. WPLOG(LL_A, LM_TAPI, ("-NDIS_STATUS_TAPI_INVALPARAM"));
  605. return NDIS_STATUS_TAPI_INVALPARAM;
  606. }
  607. // Verify the ID
  608. ValidCall = CallIsValidCall(pAdapter, pRequest->ulDeviceID);
  609. if (!ValidCall)
  610. {
  611. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiGetDevCaps NDIS_STATUS_TAPI_NODRIVER\n")));
  612. WPLOG(LL_A, LM_TAPI, ("-NDIS_STATUS_TAPI_NODRIVER"));
  613. return NDIS_STATUS_TAPI_NODRIVER;
  614. }
  615. pRequest->LineDevCaps.ulUsedSize = sizeof(pRequest->LineDevCaps);
  616. pRequest->LineDevCaps.ulAddressModes = LINEADDRESSMODE_ADDRESSID |
  617. LINEADDRESSMODE_DIALABLEADDR;
  618. pRequest->LineDevCaps.ulNumAddresses = 1;
  619. pRequest->LineDevCaps.ulBearerModes = LINEBEARERMODE_DATA;
  620. pRequest->LineDevCaps.ulDevCapFlags = LINEDEVCAPFLAGS_CLOSEDROP;
  621. pRequest->LineDevCaps.ulMaxNumActiveCalls = pAdapter->Info.Endpoints;
  622. pRequest->LineDevCaps.ulAnswerMode = LINEANSWERMODE_DROP;
  623. pRequest->LineDevCaps.ulRingModes = 1;
  624. pRequest->LineDevCaps.ulPermanentLineID = pRequest->ulDeviceID + 1;
  625. pRequest->LineDevCaps.ulMaxRate = 0;
  626. pRequest->LineDevCaps.ulMediaModes = LINEMEDIAMODE_DIGITALDATA;
  627. Status = OsSpecificTapiGetDevCaps( pRequest->ulDeviceID, pRequest );
  628. DEBUGMSG(DBG_FUNC, (DTEXT("-TapiGetDevCaps\n")));
  629. return Status;
  630. }
  631. NDIS_STATUS
  632. TapiGetExtensionId(
  633. IN PPPTP_ADAPTER pAdapter,
  634. IN OUT PNDIS_TAPI_GET_EXTENSION_ID pRequest
  635. )
  636. {
  637. BOOLEAN ValidCall;
  638. DEBUGMSG(DBG_FUNC, (DTEXT("+TapiGetExtensionId\n")));
  639. if ( pRequest == NULL || pAdapter == NULL )
  640. {
  641. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiGetExtensionId NDIS_STATUS_TAPI_INVALPARAM\n")));
  642. WPLOG(LL_A, LM_TAPI, ("-NDIS_STATUS_TAPI_INVALPARAM"));
  643. return NDIS_STATUS_TAPI_INVALPARAM;
  644. }
  645. // Verify the ID
  646. ValidCall = CallIsValidCall(pAdapter, pRequest->ulDeviceID);
  647. if (!ValidCall)
  648. {
  649. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiGetExtensionId NDIS_STATUS_TAPI_NODRIVER\n")));
  650. WPLOG(LL_A, LM_TAPI, ("-NDIS_STATUS_TAPI_NODRIVER"));
  651. return NDIS_STATUS_TAPI_NODRIVER;
  652. }
  653. // No extensions supported.
  654. pRequest->LineExtensionID.ulExtensionID0 = 0;
  655. pRequest->LineExtensionID.ulExtensionID1 = 0;
  656. pRequest->LineExtensionID.ulExtensionID2 = 0;
  657. pRequest->LineExtensionID.ulExtensionID3 = 0;
  658. DEBUGMSG(DBG_FUNC, (DTEXT("-TapiGetExtensionId\n")));
  659. return NDIS_STATUS_SUCCESS;
  660. }
  661. #define PPTP_DEVICE_TYPE_STR "PPTP"
  662. NDIS_STATUS
  663. TapiGetId(
  664. IN PPPTP_ADAPTER pAdapter,
  665. IN OUT PNDIS_TAPI_GET_ID pRequest
  666. )
  667. {
  668. PCALL_SESSION pCall;
  669. ULONG_PTR DeviceID;
  670. BOOLEAN IsNdisClass;
  671. DEBUGMSG(DBG_FUNC, (DTEXT("+TapiGetId\n")));
  672. if ( pRequest == NULL || pAdapter == NULL )
  673. {
  674. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiGetId NDIS_STATUS_TAPI_INVALPARAM\n")));
  675. WPLOG(LL_A, LM_TAPI, ("-NDIS_STATUS_TAPI_INVALPARAM"));
  676. return NDIS_STATUS_TAPI_INVALPARAM;
  677. }
  678. // Make sure this is a tapi or ndis request.
  679. if (pRequest->ulDeviceClassSize == sizeof(NDIS_DEVICECLASS_NAME) &&
  680. _strnicmp((PCHAR) pRequest + pRequest->ulDeviceClassOffset,
  681. NDIS_DEVICECLASS_NAME, pRequest->ulDeviceClassSize) == 0)
  682. {
  683. IsNdisClass = TRUE;
  684. }
  685. else if (pRequest->ulDeviceClassSize == sizeof(TAPI_DEVICECLASS_NAME) &&
  686. _strnicmp((PCHAR) pRequest + pRequest->ulDeviceClassOffset,
  687. TAPI_DEVICECLASS_NAME, pRequest->ulDeviceClassSize) == 0)
  688. {
  689. IsNdisClass = FALSE;
  690. }
  691. else
  692. {
  693. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiGetId NDIS_STATUS_TAPI_INVALDEVICECLASS\n")));
  694. WPLOG(LL_A, LM_TAPI, ("-NDIS_STATUS_TAPI_INVALDEVICECLASS"));
  695. return NDIS_STATUS_TAPI_INVALDEVICECLASS;
  696. }
  697. DBG_D(DBG_TAPI, pRequest->ulSelect);
  698. #if DBG
  699. if(pRequest->ulDeviceClassSize != 0)
  700. {
  701. DBG_S(DBG_TAPI, (PCHAR) pRequest + pRequest->ulDeviceClassOffset);
  702. }
  703. #endif
  704. switch (pRequest->ulSelect) {
  705. case LINECALLSELECT_LINE:
  706. if (!CallIsValidCall(pAdapter, TapiLineHandleToId(pRequest->hdLine)))
  707. {
  708. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiGetId NDIS_STATUS_TAPI_INVALLINEHANDLE\n")));
  709. WPLOG(LL_A, LM_TAPI, ("-NDIS_STATUS_TAPI_INVALLINEHANDLE"));
  710. return NDIS_STATUS_TAPI_INVALLINEHANDLE;
  711. }
  712. DeviceID = 0;
  713. break;
  714. case LINECALLSELECT_ADDRESS:
  715. if (!CallIsValidCall(pAdapter, TapiLineHandleToId(pRequest->hdLine)))
  716. {
  717. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiGetId NDIS_STATUS_TAPI_INVALLINEHANDLE\n")));
  718. WPLOG(LL_A, LM_TAPI, ("-NDIS_STATUS_TAPI_INVALLINEHANDLE"));
  719. return NDIS_STATUS_TAPI_INVALLINEHANDLE;
  720. }
  721. if (pRequest->ulAddressID >= TAPI_ADDR_PER_LINE)
  722. {
  723. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiGetId NDIS_STATUS_TAPI_INVALADDRESSID\n")));
  724. WPLOG(LL_A, LM_TAPI, ("-NDIS_STATUS_TAPI_INVALADDRESSID"));
  725. return NDIS_STATUS_TAPI_INVALADDRESSID;
  726. }
  727. DeviceID = 0;
  728. break;
  729. case LINECALLSELECT_CALL:
  730. pCall = CallGetCall(pAdapter, pRequest->hdCall);
  731. if (pCall == NULL)
  732. {
  733. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiGetId NDIS_STATUS_TAPI_INVALLINEHANDLE\n")));
  734. WPLOG(LL_A, LM_TAPI, ("-NDIS_STATUS_TAPI_INVALLINEHANDLE"));
  735. return NDIS_STATUS_TAPI_INVALLINEHANDLE;
  736. }
  737. TapiLineUp(pCall);
  738. DeviceID = (ULONG_PTR)pCall->NdisLinkContext;
  739. break;
  740. default:
  741. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiGetId NDIS_STATUS_FAILURE ulSelect=%d\n"), pRequest->ulSelect));
  742. WPLOG(LL_A, LM_TAPI, ("-NDIS_STATUS_FAILURE ulSelect=%d", pRequest->ulSelect));
  743. return (NDIS_STATUS_FAILURE);
  744. }
  745. // Default to the minimum amount of data we will return.
  746. pRequest->DeviceID.ulUsedSize = sizeof(VAR_STRING);
  747. if( IsNdisClass ){
  748. // The format of the DeviceID for the "ndis" class is:
  749. struct _NDIS_CLASS {
  750. ULONG_PTR hDevice;
  751. CHAR szDeviceType[1];
  752. } *pNDISClass;
  753. pRequest->DeviceID.ulNeededSize =sizeof(VAR_STRING) + sizeof(PVOID) +
  754. sizeof(DeviceID) + sizeof(PPTP_DEVICE_TYPE_STR);
  755. if (pRequest->DeviceID.ulTotalSize >= pRequest->DeviceID.ulNeededSize)
  756. {
  757. pRequest->DeviceID.ulUsedSize = pRequest->DeviceID.ulNeededSize;
  758. pRequest->DeviceID.ulStringFormat = STRINGFORMAT_BINARY;
  759. pRequest->DeviceID.ulStringSize = sizeof(DeviceID) + sizeof(PPTP_DEVICE_TYPE_STR);
  760. pNDISClass = (struct _NDIS_CLASS *)
  761. ((PUCHAR)((&pRequest->DeviceID) + 1) + sizeof(PVOID));
  762. (ULONG_PTR)pNDISClass &=
  763. ~((ULONG_PTR)sizeof(PVOID) - 1);
  764. pRequest->DeviceID.ulStringOffset = (ULONG)
  765. ((PUCHAR)pNDISClass - (PUCHAR)(&pRequest->DeviceID));
  766. pNDISClass->hDevice = DeviceID;
  767. DBG_X(DBG_TAPI, pNDISClass->hDevice);
  768. NdisMoveMemory(pNDISClass->szDeviceType, PPTP_DEVICE_TYPE_STR, sizeof(PPTP_DEVICE_TYPE_STR));
  769. }
  770. }else{
  771. // Now we need to adjust the variable field to place the device ID.
  772. pRequest->DeviceID.ulNeededSize = sizeof(VAR_STRING) + sizeof(DeviceID);
  773. if (pRequest->DeviceID.ulTotalSize >= pRequest->DeviceID.ulNeededSize)
  774. {
  775. pRequest->DeviceID.ulUsedSize = pRequest->DeviceID.ulNeededSize;
  776. pRequest->DeviceID.ulStringFormat = STRINGFORMAT_BINARY;
  777. pRequest->DeviceID.ulStringSize = sizeof(DeviceID);
  778. pRequest->DeviceID.ulStringOffset = sizeof(VAR_STRING);
  779. *(PULONG_PTR)((&pRequest->DeviceID) + 1) = DeviceID;
  780. }
  781. }
  782. //DEBUGMEM(DBG_TAPI, &pRequest->DeviceID, pRequest->DeviceID.ulUsedSize, 1);
  783. DEBUGMSG(DBG_FUNC, (DTEXT("-TapiGetId\n")));
  784. return NDIS_STATUS_SUCCESS;
  785. }
  786. VOID
  787. TapiLineDown(
  788. PCALL_SESSION pCall
  789. )
  790. {
  791. NDIS_MAC_LINE_DOWN LineDownInfo;
  792. DEBUGMSG(DBG_FUNC|DBG_CALL|DBG_TAPI, (DTEXT("+TapiLineDown %08x\n"), pCall->NdisLinkContext));
  793. if (pCall->NdisLinkContext)
  794. {
  795. LineDownInfo.NdisLinkContext = pCall->NdisLinkContext;
  796. WPLOG(LL_M, LM_TAPI, ("LINE_DOWN %!IPADDR! pCall %p, Cid %d\n",
  797. pCall->Remote.Address.Address[0].Address[0].in_addr,
  798. pCall, (ULONG)pCall->DeviceId));
  799. /*
  800. * Indicate the event to the WAN wrapper.
  801. */
  802. NdisMIndicateStatus(pCall->pAdapter->hMiniportAdapter,
  803. NDIS_STATUS_WAN_LINE_DOWN,
  804. &LineDownInfo,
  805. sizeof(LineDownInfo));
  806. pCall->NdisLinkContext = NULL;
  807. }
  808. else
  809. {
  810. WPLOG(LL_A, LM_TAPI, ("LINE_DOWN %!IPADDR! pCall %p, Cid %d - No NdisLinkContext",
  811. pCall->Remote.Address.Address[0].Address[0].in_addr,
  812. pCall, (ULONG)pCall->DeviceId));
  813. }
  814. DEBUGMSG(DBG_FUNC, (DTEXT("-TapiLineDown\n")));
  815. }
  816. VOID
  817. TapiLineUp(
  818. PCALL_SESSION pCall
  819. )
  820. {
  821. NDIS_MAC_LINE_UP LineUpInfo;
  822. DEBUGMSG(DBG_FUNC|DBG_CALL|DBG_TAPI, (DTEXT("+TapiLineUp %08x\n"), pCall));
  823. NdisAcquireSpinLock(&pCall->Lock);
  824. pCall->Close.Checklist &= ~CALL_CLOSE_LINE_DOWN;
  825. NdisReleaseSpinLock(&pCall->Lock);
  826. /*
  827. * Initialize the LINE_UP event packet.
  828. */
  829. LineUpInfo.LinkSpeed = pCall->Speed / 100;
  830. LineUpInfo.Quality = NdisWanErrorControl;
  831. LineUpInfo.SendWindow = 0;
  832. // Jeff says Win98 needs the DeviceID as the connection wrapper ID, but
  833. // TonyBe says NT needs an absolutely unique ID, which hTapiCall is.
  834. // hTapiCall is probably more correct according to Tapi rules, but we make
  835. // allowances.
  836. LineUpInfo.ConnectionWrapperID = OS_CONNECTION_WRAPPER_ID;
  837. LineUpInfo.NdisLinkHandle = (NDIS_HANDLE) DeviceIdToLinkHandle(pCall->FullDeviceId);
  838. LineUpInfo.NdisLinkContext = pCall->NdisLinkContext;
  839. WPLOG(LL_M, LM_TAPI, ("LINE_UP %!IPADDR! pCall %p, Cid %d",
  840. pCall->Remote.Address.Address[0].Address[0].in_addr,
  841. pCall, (ULONG)pCall->DeviceId));
  842. /*
  843. * Indicate the event to the WAN wrapper.
  844. */
  845. NdisMIndicateStatus(pCall->pAdapter->hMiniportAdapter,
  846. NDIS_STATUS_WAN_LINE_UP,
  847. &LineUpInfo,
  848. sizeof(LineUpInfo));
  849. NdisAcquireSpinLock(&pCall->Lock);
  850. pCall->NdisLinkContext = LineUpInfo.NdisLinkContext;
  851. NdisReleaseSpinLock(&pCall->Lock);
  852. DBG_X(DBG_TAPI, LineUpInfo.NdisLinkContext);
  853. DEBUGMSG(DBG_FUNC, (DTEXT("-TapiLineUp\n")));
  854. }
  855. typedef struct {
  856. TA_IP_ADDRESS TargetAddress[MAX_TARGET_ADDRESSES];
  857. ULONG NumAddresses;
  858. ULONG CurrentAddress;
  859. } MAKE_CALL_CONTEXT, *PMAKE_CALL_CONTEXT;
  860. VOID
  861. TapipParseIpAddressesAndCallerId(
  862. IN PUCHAR pAddressList,
  863. IN ULONG ListLength,
  864. IN PCALL_SESSION pCall,
  865. IN OUT PTA_IP_ADDRESS TargetAddress,
  866. IN OUT PULONG pulCountAddresses
  867. )
  868. {
  869. BOOLEAN ValidAddress = FALSE;
  870. ULONG NumTargetAddresses = 0;
  871. PUCHAR pEndAddressList;
  872. ULONG MaxTargetAddresses = *pulCountAddresses;
  873. DEBUGMSG(DBG_FUNC, (DTEXT("+TapipParseAddresses\n")));
  874. // TAPI gives us an address of the following forms:
  875. //
  876. // [ IP Address ... IP Address ] [ Phone Number ]
  877. //
  878. // It begins with a list of addresses to try, and an optional phone number
  879. // if the remote device is an access concentrator.
  880. NdisZeroMemory(TargetAddress, sizeof(TA_IP_ADDRESS) * MaxTargetAddresses);
  881. *pulCountAddresses = 0;
  882. pEndAddressList = pAddressList + ListLength;
  883. if(ListLength < 2)
  884. {
  885. return; // invalid length
  886. }
  887. // Make sure it's null terminated
  888. if(pAddressList[ListLength - 1] != '\0')
  889. {
  890. pAddressList[ListLength - 1] = '\0';
  891. }
  892. ValidAddress = TRUE;
  893. while (ValidAddress && pAddressList<pEndAddressList)
  894. {
  895. pAddressList = StringToIpAddress(pAddressList,
  896. &TargetAddress[NumTargetAddresses],
  897. &ValidAddress);
  898. if (ValidAddress)
  899. {
  900. if (++NumTargetAddresses==MaxTargetAddresses)
  901. {
  902. // We've hit the limit of what we'll take. Throw the rest.
  903. while (ValidAddress && pAddressList<pEndAddressList)
  904. {
  905. TA_IP_ADDRESS ThrowAway;
  906. pAddressList = StringToIpAddress(pAddressList,
  907. &ThrowAway,
  908. &ValidAddress);
  909. }
  910. }
  911. }
  912. }
  913. // We've got the addresses. Now nab the phone #
  914. {
  915. ULONG Digits = 0;
  916. while (pAddressList<pEndAddressList && *pAddressList && (*pAddressList==' ' || *pAddressList=='\t'))
  917. {
  918. pAddressList++;
  919. }
  920. while (pAddressList<pEndAddressList && *pAddressList &&
  921. Digits<MAX_PHONE_NUMBER_LENGTH-1)
  922. {
  923. pCall->CallerId[Digits++] = *pAddressList++;
  924. }
  925. pCall->CallerId[Digits] = '\0';
  926. #if 0
  927. // This apparently breaks Alcatel
  928. if (!Digits)
  929. {
  930. IpAddressToString(htonl(pCall->Remote.Address.Address[0].Address[0].in_addr), pCall->CallerId);
  931. }
  932. #endif
  933. DEBUGMSG(DBG_CALL, (DTEXT("Dialing %hs\n"), pCall->CallerId));
  934. }
  935. *pulCountAddresses = NumTargetAddresses;
  936. DEBUGMSG(DBG_FUNC, (DTEXT("-TapipParseAddresses\n")));
  937. }
  938. VOID
  939. TapipMakeCallCallback(
  940. PPPTP_WORK_ITEM pWorkItem
  941. )
  942. {
  943. PCALL_SESSION pCall;
  944. PPPTP_ADAPTER pAdapter = pWorkItem->Context;
  945. PNDIS_TAPI_MAKE_CALL pRequest = pWorkItem->pBuffer;
  946. NDIS_STATUS Status;
  947. DEBUGMSG(DBG_FUNC, (DTEXT("+TapipMakeCallCallback\n")));
  948. pCall = CallGetCall(pAdapter, pRequest->hdCall);
  949. if (!pCall)
  950. {
  951. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapipMakeCallCallback NDIS_STATUS_TAPI_INUSE\n")));
  952. WPLOG(LL_A, LM_TAPI, ("-NDIS_STATUS_TAPI_INUSE"));
  953. NdisMQueryInformationComplete(pAdapter->hMiniportAdapter, NDIS_STATUS_TAPI_INUSE);
  954. return;
  955. }
  956. NdisAcquireSpinLock(&pCall->Lock);
  957. CallSetState(pCall, STATE_CALL_DIALING, 0, LOCKED);
  958. NdisMSetTimer(&pCall->DialTimer, 60*1000);
  959. pCall->Close.Checklist &= ~(CALL_CLOSE_DROP|CALL_CLOSE_DROP_COMPLETE|CALL_CLOSE_CLOSE_CALL);
  960. pCall->Close.Checklist &= ~(CALL_CLOSE_DISCONNECT|CALL_CLOSE_CLEANUP_STATE);
  961. NdisReleaseSpinLock(&pCall->Lock);
  962. Status = CtlConnectCall(pAdapter, pCall, &pCall->Remote.Address);
  963. NdisAcquireSpinLock(&pCall->Lock);
  964. if (Status==NDIS_STATUS_PENDING)
  965. {
  966. Status = NDIS_STATUS_SUCCESS;
  967. }
  968. else if (Status!=NDIS_STATUS_SUCCESS)
  969. {
  970. // We weren't successful, so we won't be getting these calls from tapi
  971. pCall->Close.Checklist |= (CALL_CLOSE_DROP|CALL_CLOSE_DROP_COMPLETE|CALL_CLOSE_CLOSE_CALL);
  972. }
  973. pCall->Remote.Address.Address[0].Address[0].sin_port = htons(PptpProtocolNumber);
  974. NdisReleaseSpinLock(&pCall->Lock);
  975. NdisMQueryInformationComplete(pAdapter->hMiniportAdapter, Status);
  976. DEBUGMSG(DBG_FUNC, (DTEXT("-TapipMakeCallCallback\n")));
  977. }
  978. NDIS_STATUS
  979. TapiMakeCall(
  980. IN PPPTP_ADAPTER pAdapter,
  981. IN OUT PNDIS_TAPI_MAKE_CALL pRequest
  982. )
  983. {
  984. PCALL_SESSION pCall;
  985. NDIS_STATUS Status;
  986. ULONG NumAddresses = 1;
  987. PUCHAR pAddressList = (PUCHAR)pRequest + pRequest->ulDestAddressOffset;
  988. DEBUGMSG(DBG_FUNC, (DTEXT("+TapiMakeCall\n")));
  989. if ( pRequest == NULL || pAdapter == NULL )
  990. {
  991. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiMakeCall NDIS_STATUS_TAPI_INVALPARAM\n")));
  992. WPLOG(LL_A, LM_TAPI, ("-NDIS_STATUS_TAPI_INVALPARAM"));
  993. return NDIS_STATUS_TAPI_INVALPARAM;
  994. }
  995. if(!pAdapter->Tapi.Open)
  996. {
  997. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiMakeCall NDIS_STATUS_TAPI_NODEVICE\n")));
  998. WPLOG(LL_A, LM_TAPI, ("-NDIS_STATUS_TAPI_NODEVICE"));
  999. return NDIS_STATUS_TAPI_NODEVICE;
  1000. }
  1001. if (!CallIsValidCall(pAdapter, TapiLineHandleToId(pRequest->hdLine)))
  1002. {
  1003. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiMakeCall NDIS_STATUS_TAPI_INVALLINEHANDLE\n")));
  1004. WPLOG(LL_A, LM_TAPI, ("-NDIS_STATUS_TAPI_INVALLINEHANDLE"));
  1005. return NDIS_STATUS_TAPI_INVALLINEHANDLE;
  1006. }
  1007. pCall = CallFindAndLock(pAdapter, STATE_CALL_IDLE, FIND_OUTGOING);
  1008. if (!pCall)
  1009. {
  1010. DEBUGMSG(DBG_ERROR, (DTEXT("-TapiMakeCall NDIS_STATUS_TAPI_INUSE\n")));
  1011. WPLOG(LL_A, LM_TAPI, ("-NDIS_STATUS_TAPI_INUSE"));
  1012. return NDIS_STATUS_TAPI_INUSE;
  1013. }
  1014. if (pCall->State != STATE_CALL_IDLE)
  1015. {
  1016. NdisReleaseSpinLock(&pCall->Lock);
  1017. DEBUGMSG(DBG_ERROR, (DTEXT("-TapiMakeCall NDIS_STATUS_TAPI_INUSE\n")));
  1018. WPLOG(LL_A, LM_TAPI, ("-NDIS_STATUS_TAPI_INUSE"));
  1019. return NDIS_STATUS_TAPI_INUSE;
  1020. }
  1021. // Save the handle tapi provides
  1022. ASSERT(!pCall->hTapiCall);
  1023. pCall->hTapiCall = pRequest->htCall;
  1024. pCall->Inbound = FALSE;
  1025. // our handle for tapi to this call is the device id
  1026. pRequest->hdCall = pCall->FullDeviceId;
  1027. WPLOG(LL_M, LM_TAPI, ("MAKECALL pCall %p, Cid %d, hTapiCall %Ix, hdCall %d",
  1028. pCall, (ULONG)pCall->DeviceId, pCall->hTapiCall, (ULONG)pRequest->hdCall));
  1029. CallSetState(pCall, STATE_CALL_OFFHOOK, 0, LOCKED);
  1030. pCall->PendingUse = FALSE;
  1031. NdisReleaseSpinLock(&pCall->Lock);
  1032. // We currently support one IP address only
  1033. TapipParseIpAddressesAndCallerId(pAddressList,
  1034. pRequest->ulDestAddressSize,
  1035. pCall,
  1036. &pCall->Remote.Address,
  1037. &NumAddresses);
  1038. if(NumAddresses != 1)
  1039. {
  1040. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapipMakeCall NDIS_STATUS_TAPI_INVALCALLPARAMS\n")));
  1041. WPLOG(LL_A, LM_TAPI, ("-NDIS_STATUS_TAPI_INVALCALLPARAMS"));
  1042. Status = NDIS_STATUS_TAPI_INVALCALLPARAMS;
  1043. }
  1044. else
  1045. {
  1046. // We got a valid IP address.
  1047. // Schedule a work item so we can issue a CtlCreateCall at passive level.
  1048. Status = ScheduleWorkItem(TapipMakeCallCallback,
  1049. pAdapter,
  1050. pRequest,
  1051. 0);
  1052. }
  1053. if (Status==NDIS_STATUS_SUCCESS)
  1054. {
  1055. // Keep the pRequest around until the callback.
  1056. Status = NDIS_STATUS_PENDING;
  1057. }
  1058. else
  1059. {
  1060. CallSetState(pCall, STATE_CALL_CLEANUP, LINEDISCONNECTMODE_UNKNOWN, UNLOCKED);
  1061. CallCleanup(pCall, UNLOCKED);
  1062. }
  1063. DEBUGMSG(DBG_FUNC, (DTEXT("-TapiMakeCall %08x\n"), Status));
  1064. return Status;
  1065. }
  1066. NDIS_STATUS
  1067. TapiNegotiateExtVersion(
  1068. IN PPPTP_ADAPTER pAdapter,
  1069. IN OUT PNDIS_TAPI_NEGOTIATE_EXT_VERSION pRequest
  1070. )
  1071. {
  1072. DEBUGMSG(DBG_FUNC, (DTEXT("+TapiNegotiateExtVersion Low=%08x Hi=%08x\n"),
  1073. pRequest ? pRequest->ulLowVersion : 0, pRequest ? pRequest->ulHighVersion : 0));
  1074. if ( pRequest == NULL || pAdapter == NULL )
  1075. {
  1076. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiNegotiateExtVersion NDIS_STATUS_TAPI_INVALPARAM\n")));
  1077. WPLOG(LL_A, LM_TAPI, ("-TapiNegotiateExtVersion NDIS_STATUS_TAPI_INVALPARAM"));
  1078. return NDIS_STATUS_TAPI_INVALPARAM;
  1079. }
  1080. if (pRequest->ulLowVersion < TAPI_EXT_VERSION ||
  1081. pRequest->ulHighVersion > TAPI_EXT_VERSION)
  1082. {
  1083. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiNegotiateExtVersion NDIS_STATUS_TAPI_INCOMPATIBLEEXTVERSION\n")));
  1084. WPLOG(LL_A, LM_TAPI, ("-TapiNegotiateExtVersion NDIS_STATUS_TAPI_INCOMPATIBLEEXTVERSION"));
  1085. return NDIS_STATUS_TAPI_INCOMPATIBLEEXTVERSION;
  1086. }
  1087. DEBUGMSG(DBG_FUNC, (DTEXT("-TapiNegotiateExtVersion\n")));
  1088. return NDIS_STATUS_SUCCESS;
  1089. }
  1090. VOID
  1091. TapipPassiveOpen(
  1092. PPPTP_WORK_ITEM pWorkItem
  1093. )
  1094. {
  1095. PPPTP_ADAPTER pAdapter = pWorkItem->Context;
  1096. DEBUGMSG(DBG_FUNC, (DTEXT("+TapipPassiveOpen\n")));
  1097. // We only come here if PptpInitialized = FALSE;
  1098. // It's a mechanism to defer opening tcp handles until tcp is
  1099. // actually available, as it may not always be during startup/setup
  1100. PptpInitialize(pAdapter);
  1101. NdisMQueryInformationComplete(pAdapter->hMiniportAdapter, NDIS_STATUS_SUCCESS);
  1102. DEBUGMSG(DBG_FUNC, (DTEXT("-TapipPassiveOpen\n")));
  1103. }
  1104. NDIS_STATUS
  1105. TapiOpen(
  1106. IN PPPTP_ADAPTER pAdapter,
  1107. IN OUT PNDIS_TAPI_OPEN pRequest
  1108. )
  1109. {
  1110. PCALL_SESSION pCall;
  1111. DEBUGMSG(DBG_FUNC, (DTEXT("+TapiOpen\n")));
  1112. if ( pRequest == NULL || pAdapter == NULL )
  1113. {
  1114. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiOpen NDIS_STATUS_TAPI_INVALPARAM\n")));
  1115. WPLOG(LL_A, LM_TAPI, ("-NDIS_STATUS_TAPI_INVALPARAM"));
  1116. return NDIS_STATUS_TAPI_INVALPARAM;
  1117. }
  1118. if (!CallIsValidCall(pAdapter, pRequest->ulDeviceID))
  1119. {
  1120. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiOpen NDIS_STATUS_TAPI_NODRIVER\n")));
  1121. WPLOG(LL_A, LM_TAPI, ("-NDIS_STATUS_TAPI_NODRIVER"));
  1122. return NDIS_STATUS_TAPI_NODRIVER;
  1123. }
  1124. NdisAcquireSpinLock(&pAdapter->Lock);
  1125. if (pAdapter->Tapi.Open)
  1126. {
  1127. NdisReleaseSpinLock(&pAdapter->Lock);
  1128. return NDIS_STATUS_TAPI_ALLOCATED;
  1129. }
  1130. pAdapter->Tapi.Open = TRUE;
  1131. pAdapter->Tapi.hTapiLine = pRequest->htLine;
  1132. pRequest->hdLine = TapiIdToLineHandle(pRequest->ulDeviceID);
  1133. NdisReleaseSpinLock(&pAdapter->Lock);
  1134. if (!PptpInitialized)
  1135. {
  1136. if (ScheduleWorkItem(TapipPassiveOpen, pAdapter, NULL, 0)==NDIS_STATUS_SUCCESS)
  1137. {
  1138. DEBUGMSG(DBG_FUNC, (DTEXT("-TapiOpen PENDING\n")));
  1139. return NDIS_STATUS_PENDING;
  1140. }
  1141. }
  1142. DEBUGMSG(DBG_FUNC, (DTEXT("-TapiOpen\n")));
  1143. return NDIS_STATUS_SUCCESS;
  1144. }
  1145. VOID
  1146. TapipPassiveProviderInitialize(
  1147. PPPTP_WORK_ITEM pWorkItem
  1148. )
  1149. {
  1150. PPPTP_ADAPTER pAdapter = pWorkItem->Context;
  1151. DEBUGMSG(DBG_FUNC, (DTEXT("+TapipPassiveProviderInitialize\n")));
  1152. // We initialize this here because TCP may not be available in MiniportInitialize
  1153. // We don't uninit until MiniportHalt. CtdiInitialize will just return quietly
  1154. // if it's already initialized, so we can come through here several times
  1155. // safely.
  1156. PptpInitialize(pAdapter); // Ignore the return status.
  1157. NdisMQueryInformationComplete(pAdapter->hMiniportAdapter, NDIS_STATUS_SUCCESS);
  1158. DEBUGMSG(DBG_FUNC, (DTEXT("-TapipPassiveProviderInitialize\n")));
  1159. }
  1160. NDIS_STATUS
  1161. TapiProviderInitialize(
  1162. IN PPPTP_ADAPTER pAdapter,
  1163. IN OUT PNDIS_TAPI_PROVIDER_INITIALIZE pRequest
  1164. )
  1165. {
  1166. NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
  1167. DEBUGMSG(DBG_FUNC, (DTEXT("+TapiProviderInitialize\n")));
  1168. if ( pRequest == NULL || pAdapter == NULL )
  1169. {
  1170. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiProviderInitialize NDIS_STATUS_TAPI_INVALPARAM\n")));
  1171. WPLOG(LL_A, LM_TAPI, ("-NDIS_STATUS_TAPI_INVALPARAM"));
  1172. return NDIS_STATUS_TAPI_INVALPARAM;
  1173. }
  1174. pAdapter->Tapi.DeviceIdBase = pRequest->ulDeviceIDBase;
  1175. pRequest->ulNumLineDevs = 1;
  1176. pRequest->ulProviderID = (ULONG_PTR)pAdapter;
  1177. if (!PptpInitialized)
  1178. {
  1179. Status = ScheduleWorkItem(TapipPassiveProviderInitialize, pAdapter, NULL, 0);
  1180. if (Status==NDIS_STATUS_SUCCESS)
  1181. {
  1182. // Keep the pRequest around until the callback.
  1183. Status = NDIS_STATUS_PENDING;
  1184. }
  1185. }
  1186. DEBUGMSG(DBG_FUNC, (DTEXT("-TapiProviderInitialize %08x\n"), Status));
  1187. return Status;
  1188. }
  1189. VOID
  1190. TapipPassiveProviderShutdown(
  1191. PPPTP_WORK_ITEM pWorkItem
  1192. )
  1193. {
  1194. PPPTP_ADAPTER pAdapter = pWorkItem->Context;
  1195. ULONG i;
  1196. DEBUGMSG(DBG_FUNC|DBG_TAPI, (DTEXT("+TapipPassiveProviderShutdown\n")));
  1197. NdisAcquireSpinLock(&pAdapter->Lock);
  1198. pAdapter->Tapi.Open = FALSE;
  1199. NdisReleaseSpinLock(&pAdapter->Lock);
  1200. for (i=0; i<pAdapter->Info.Endpoints; i++)
  1201. {
  1202. // PCALL_SESSION pCall = CallGetCall(pAdapter, i);
  1203. PCALL_SESSION pCall = pAdapter->pCallArray[i];
  1204. if (IS_CALL(pCall))
  1205. {
  1206. NdisAcquireSpinLock(&pCall->Lock);
  1207. if (pCall->State>STATE_CALL_IDLE && pCall->State<=STATE_CALL_CLEANUP)
  1208. {
  1209. pCall->Open = FALSE;
  1210. CallSetState(pCall, STATE_CALL_CLEANUP, LINEDISCONNECTMODE_NORMAL, LOCKED);
  1211. // CALL_SESSION will be reused
  1212. // CallDetachFromAdapter(pCall);
  1213. pCall->Close.Checklist |= (CALL_CLOSE_DROP|CALL_CLOSE_DROP_COMPLETE|CALL_CLOSE_CLOSE_CALL);
  1214. CallCleanup(pCall, LOCKED);
  1215. }
  1216. NdisReleaseSpinLock(&pCall->Lock);
  1217. }
  1218. }
  1219. if (pAdapter->hCtdiDg)
  1220. {
  1221. CtdiClose(pAdapter->hCtdiDg);
  1222. pAdapter->hCtdiDg = NULL;
  1223. }
  1224. if (pAdapter->hCtdiListen)
  1225. {
  1226. CtdiClose(pAdapter->hCtdiListen);
  1227. pAdapter->hCtdiListen = NULL;
  1228. }
  1229. PptpInitialized = FALSE;
  1230. NdisMSetInformationComplete(pAdapter->hMiniportAdapter, NDIS_STATUS_SUCCESS);
  1231. DEBUGMSG(DBG_FUNC, (DTEXT("-TapipPassiveProviderShutdown\n")));
  1232. }
  1233. NDIS_STATUS
  1234. TapiProviderShutdown(
  1235. IN PPPTP_ADAPTER pAdapter,
  1236. IN OUT PNDIS_TAPI_PROVIDER_SHUTDOWN pRequest
  1237. )
  1238. {
  1239. NDIS_STATUS Status;
  1240. DEBUGMSG(DBG_FUNC, (DTEXT("+TapiProviderShutdown\n")));
  1241. if ( pRequest == NULL || pAdapter == NULL )
  1242. {
  1243. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiProviderShutdown NDIS_STATUS_TAPI_INVALPARAM\n")));
  1244. WPLOG(LL_A, LM_TAPI, ("-NDIS_STATUS_TAPI_INVALPARAM"));
  1245. return NDIS_STATUS_TAPI_INVALPARAM;
  1246. }
  1247. Status = ScheduleWorkItem(TapipPassiveProviderShutdown, pAdapter, NULL, 0);
  1248. if (Status==NDIS_STATUS_SUCCESS)
  1249. {
  1250. Status = NDIS_STATUS_PENDING;
  1251. }
  1252. DEBUGMSG(DBG_FUNC|DBG_ERR(Status), (DTEXT("-TapiProviderShutdown %08x\n"), Status));
  1253. return Status;
  1254. }
  1255. VOID
  1256. TapipSetDefaultMediaDetectionCallback(
  1257. PPPTP_WORK_ITEM pWorkItem
  1258. )
  1259. {
  1260. PPPTP_ADAPTER pAdapter = pWorkItem->Context;
  1261. PNDIS_TAPI_SET_DEFAULT_MEDIA_DETECTION pRequest = pWorkItem->pBuffer;
  1262. NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
  1263. DEBUGMSG(DBG_FUNC, (DTEXT("+TapipSetDefaultMediaDetectionCallback\n")));
  1264. if (pRequest->ulMediaModes&LINEMEDIAMODE_DIGITALDATA)
  1265. {
  1266. Status = CtlListen(pAdapter);
  1267. }
  1268. else if (pAdapter->hCtdiListen)
  1269. {
  1270. CtdiClose(pAdapter->hCtdiListen);
  1271. pAdapter->hCtdiListen = NULL;
  1272. }
  1273. NdisMSetInformationComplete(pAdapter->hMiniportAdapter, Status);
  1274. DEBUGMSG(DBG_FUNC, (DTEXT("-TapipSetDefaultMediaDetectionCallback\n")));
  1275. }
  1276. NDIS_STATUS
  1277. TapiSetDefaultMediaDetection(
  1278. IN PPPTP_ADAPTER pAdapter,
  1279. IN OUT PNDIS_TAPI_SET_DEFAULT_MEDIA_DETECTION pRequest
  1280. )
  1281. {
  1282. NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
  1283. DEBUGMSG(DBG_FUNC, (DTEXT("+TapiSetDefaultMediaDetection\n")));
  1284. if ( pRequest == NULL || pAdapter == NULL )
  1285. {
  1286. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiSetDefaultMediaDetection NDIS_STATUS_TAPI_INVALPARAM\n")));
  1287. WPLOG(LL_A, LM_TAPI, ("-TapiSetDefaultMediaDetection NDIS_STATUS_TAPI_INVALPARAM"));
  1288. return NDIS_STATUS_TAPI_INVALPARAM;
  1289. }
  1290. // Verify the ID
  1291. if (!CallIsValidCall(pAdapter, TapiLineHandleToId(pRequest->hdLine)))
  1292. {
  1293. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiSetDefaultMediaDetection NDIS_STATUS_TAPI_INVALLINEHANDLE\n")));
  1294. WPLOG(LL_A, LM_TAPI, ("-TapiSetDefaultMediaDetection NDIS_STATUS_TAPI_INVALLINEHANDLE"));
  1295. return NDIS_STATUS_TAPI_INVALLINEHANDLE;
  1296. }
  1297. // This is the OID to make us start accepting calls.
  1298. DEBUGMSG(DBG_TAPI, (DTEXT("MediaModes: %x\n"), pRequest->ulMediaModes));
  1299. // Schedule a work item so we can issue a CtlListen at passive level.
  1300. Status = ScheduleWorkItem(TapipSetDefaultMediaDetectionCallback,
  1301. pAdapter,
  1302. pRequest,
  1303. 0);
  1304. if (Status==NDIS_STATUS_SUCCESS)
  1305. {
  1306. Status = NDIS_STATUS_PENDING;
  1307. }
  1308. DEBUGMSG(DBG_FUNC, (DTEXT("-TapiSetDefaultMediaDetection %08x\n"), Status));
  1309. return NDIS_STATUS_PENDING;
  1310. }
  1311. NDIS_STATUS
  1312. TapiSetStatusMessages(
  1313. IN PPPTP_ADAPTER pAdapter,
  1314. IN OUT PNDIS_TAPI_SET_STATUS_MESSAGES pRequest
  1315. )
  1316. {
  1317. DEBUGMSG(DBG_FUNC, (DTEXT("+TapiSetStatusMessages\n")));
  1318. if ( pRequest == NULL || pAdapter == NULL )
  1319. {
  1320. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiSetStatusMessages NDIS_STATUS_TAPI_INVALPARAM\n")));
  1321. WPLOG(LL_A, LM_TAPI, ("-NDIS_STATUS_TAPI_INVALPARAM"));
  1322. return NDIS_STATUS_TAPI_INVALPARAM;
  1323. }
  1324. if (!CallIsValidCall(pAdapter, TapiLineHandleToId(pRequest->hdLine)))
  1325. {
  1326. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiSetDefaultMediaDetection NDIS_STATUS_TAPI_INVALLINEHANDLE\n")));
  1327. WPLOG(LL_A, LM_TAPI, ("-NDIS_STATUS_TAPI_INVALLINEHANDLE"));
  1328. return NDIS_STATUS_TAPI_INVALLINEHANDLE;
  1329. }
  1330. pAdapter->Tapi.LineStateMask = pRequest->ulLineStates;
  1331. DEBUGMSG(DBG_FUNC, (DTEXT("-TapiSetStatusMessages\n")));
  1332. return NDIS_STATUS_SUCCESS;
  1333. }