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.

698 lines
16 KiB

  1. /*++
  2. Copyright (c) 1995-1996 Microsoft Corporation
  3. Module Name:
  4. pxcm.c
  5. Abstract:
  6. This module contains the Call Manager (CM_) entry points listed
  7. in the protocol characteristics table. These entry points are called
  8. by the NDIS wrapper on behalf of requests made by a client.
  9. Author:
  10. Richard Machin (RMachin)
  11. Revision History:
  12. Who When What
  13. -------- -------- ----------------------------------------------
  14. RMachin 10-03-96 created
  15. tonybe 01-23-99 rewrite and cleanup
  16. Notes:
  17. --*/
  18. #include "precomp.h"
  19. #define MODULE_NUMBER MODULE_CM
  20. #define _FILENUMBER 'MCXP'
  21. NDIS_STATUS
  22. PxCmCreateVc(
  23. IN NDIS_HANDLE ProtocolAfContext,
  24. IN NDIS_HANDLE NdisVcHandle,
  25. OUT PNDIS_HANDLE pProtocolVcContext
  26. )
  27. /*++
  28. Routine Description:
  29. We do not allow a client of the proxy to create a Vc ever!
  30. Arguments:
  31. Return Value:
  32. NDIS_STATUS_SUCCESS if everything goes off well right here
  33. NDIS_STATUS_XXXX to indicate any error.
  34. --*/
  35. {
  36. PXDEBUGP(PXD_FATAL, PXM_CM,
  37. ("PxCmCreateVc: Should never be called!\n"));
  38. ASSERT(0);
  39. return(NDIS_STATUS_FAILURE);
  40. }
  41. NDIS_STATUS
  42. PxCmDeleteVc(
  43. IN NDIS_HANDLE ProtocolVcContext
  44. )
  45. /*++
  46. Routine Description:
  47. We do not allow a client to delete a vc!
  48. Arguments:
  49. Return Value:
  50. NDIS_STATUS_SUCCESS if everything goes off well right here
  51. NDIS_STATUS_XXXX to indicate any error.
  52. --*/
  53. {
  54. PXDEBUGP(PXD_FATAL, PXM_CM,
  55. ("PxCmDeleteVc: Should never be called!\n"));
  56. ASSERT(0);
  57. return(NDIS_STATUS_FAILURE);
  58. }
  59. NDIS_STATUS
  60. PxCmOpenAf(
  61. IN NDIS_HANDLE BindingContext,
  62. IN PCO_ADDRESS_FAMILY AddressFamily,
  63. IN NDIS_HANDLE NdisAfHandle,
  64. OUT PNDIS_HANDLE CallMgrAfContext
  65. )
  66. /*++
  67. Routine Description:
  68. This routine creats an Af context for the client that is opening
  69. our address family. The Af context is threaded up on the adapter
  70. block.
  71. Arguments:
  72. Return Value:
  73. NDIS_STATUS_SUCCESS if everything goes off well right here
  74. NDIS_STATUS_XXXX to indicate any error.
  75. --*/
  76. {
  77. PPX_CM_AF pCmAf;
  78. PPX_ADAPTER pAdapter;
  79. PXDEBUGP(PXD_LOUD, PXM_CM, ("PxCmOpenAf: AF: %x\n",AddressFamily->AddressFamily));
  80. //
  81. // Make sure the address family being opened is ours
  82. //
  83. if(AddressFamily->AddressFamily != CO_ADDRESS_FAMILY_TAPI) {
  84. PXDEBUGP(PXD_ERROR, PXM_CM,
  85. ("PxCmOpenAf: not Proxy address family: %x\n",
  86. AddressFamily->AddressFamily));
  87. return(NDIS_STATUS_BAD_VERSION);
  88. }
  89. AdapterFromCmBindContext(BindingContext, pAdapter);
  90. NdisAcquireSpinLock(&pAdapter->Lock);
  91. if (pAdapter->State != PX_ADAPTER_OPEN) {
  92. NdisReleaseSpinLock(&pAdapter->Lock);
  93. return (NDIS_STATUS_CLOSING);
  94. }
  95. NdisReleaseSpinLock(&pAdapter->Lock);
  96. pCmAf =
  97. PxAllocateCmAf(AddressFamily);
  98. if (pCmAf == NULL) {
  99. PXDEBUGP(PXD_ERROR, PXM_CM, ("PXCmOpenAf: AfBlock memory allocation failed!\n"));
  100. return (NDIS_STATUS_RESOURCES);
  101. }
  102. pCmAf->NdisAfHandle = NdisAfHandle;
  103. pCmAf->State = PX_AF_OPENED;
  104. pCmAf->Adapter = pAdapter;
  105. NdisAcquireSpinLock(&pAdapter->Lock);
  106. InsertTailList(&pAdapter->CmAfList, &pCmAf->Linkage);
  107. REF_ADAPTER(pAdapter);
  108. NdisReleaseSpinLock(&pAdapter->Lock);
  109. PXDEBUGP(PXD_LOUD, PXM_CM, ("PxCmOpenAf: CmAf %p, NdisAfHandle is %p\n",
  110. pCmAf,NdisAfHandle));
  111. *CallMgrAfContext = pCmAf;
  112. return(NDIS_STATUS_SUCCESS);
  113. }
  114. NDIS_STATUS
  115. PxCmCloseAf(
  116. IN NDIS_HANDLE CallMgrAfContext
  117. )
  118. /*++
  119. Routine Description:
  120. The client is closing the open of this address family.
  121. Arguments:
  122. Return Value:
  123. NDIS_STATUS_SUCCESS if everything goes off well right here
  124. NDIS_STATUS_XXXX to indicate any error.
  125. --*/
  126. {
  127. PPX_CM_AF pCmAf;
  128. PPX_ADAPTER pAdapter;
  129. pCmAf = (PPX_CM_AF)CallMgrAfContext;
  130. //ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
  131. PXDEBUGP(PXD_LOUD, PXM_CM, ("PxCmCloseAf: CmAf %p\n", pCmAf));
  132. //
  133. // There should not be any open saps on this af!
  134. //
  135. ASSERT(IsListEmpty(&pCmAf->CmSapList) == TRUE);
  136. //
  137. // There should not be any active Vc's on this af!
  138. //
  139. ASSERT(IsListEmpty(&pCmAf->VcList) == TRUE);
  140. pAdapter = pCmAf->Adapter;
  141. NdisAcquireSpinLock(&pAdapter->Lock);
  142. RemoveEntryList(&pCmAf->Linkage);
  143. DEREF_ADAPTER_LOCKED(pAdapter);
  144. NdisAcquireSpinLock(&pCmAf->Lock);
  145. pCmAf->State = PX_AF_CLOSED;
  146. pCmAf->Linkage.Flink =
  147. pCmAf->Linkage.Blink = (PLIST_ENTRY)pCmAf;
  148. DEREF_CM_AF_LOCKED(pCmAf);
  149. //ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
  150. return (NDIS_STATUS_PENDING);
  151. }
  152. NDIS_STATUS
  153. PxCmRegisterSap(
  154. IN NDIS_HANDLE CallMgrAfContext,
  155. IN PCO_SAP Sap,
  156. IN NDIS_HANDLE NdisSapHandle,
  157. OUT PNDIS_HANDLE CallMgrSapContext
  158. )
  159. /*++
  160. Routine Description:
  161. Arguments:
  162. Return Value:
  163. NDIS_STATUS_SUCCESS if everything goes off well right here
  164. NDIS_STATUS_XXXX to indicate any error.
  165. --*/
  166. {
  167. PPX_CM_AF pCmAf;
  168. PPX_CM_SAP pCmSap;
  169. PPX_ADAPTER pAdapter;
  170. pCmAf = (PPX_CM_AF)CallMgrAfContext;
  171. PXDEBUGP(PXD_LOUD, PXM_CM, ("PxCmRegisterSap: CmAf %p\n", pCmAf));
  172. NdisAcquireSpinLock(&pCmAf->Lock);
  173. if (pCmAf->State != PX_AF_OPENED) {
  174. PXDEBUGP(PXD_WARNING, PXM_CM,
  175. ("PxCmRegisterSap: Invalid state %x\n", pCmAf->State));
  176. NdisReleaseSpinLock(&pCmAf->Lock);
  177. return (NDIS_STATUS_FAILURE);
  178. }
  179. pAdapter = pCmAf->Adapter;
  180. NdisReleaseSpinLock(&pCmAf->Lock);
  181. NdisAcquireSpinLock(&pAdapter->Lock);
  182. if (pAdapter->State != PX_ADAPTER_OPEN) {
  183. NdisReleaseSpinLock(&pAdapter->Lock);
  184. return (NDIS_STATUS_CLOSING);
  185. }
  186. NdisReleaseSpinLock(&pAdapter->Lock);
  187. //
  188. // Allocate memory for the Sap
  189. //
  190. pCmSap = PxAllocateCmSap(Sap);
  191. if (pCmSap == NULL) {
  192. PXDEBUGP(PXD_WARNING, PXM_CM,
  193. ("PxCmRegisterSap: Error allocating memory for sap %p\n", Sap));
  194. NdisReleaseSpinLock(&pCmAf->Lock);
  195. return (NDIS_STATUS_RESOURCES);
  196. }
  197. NdisAcquireSpinLock(&pCmAf->Lock);
  198. pCmSap->NdisSapHandle = NdisSapHandle;
  199. pCmSap->CmAf = pCmAf;
  200. InsertTailList(&pCmAf->CmSapList, &pCmSap->Linkage);
  201. REF_CM_AF(pCmAf);
  202. NdisReleaseSpinLock(&pCmAf->Lock);
  203. *CallMgrSapContext = pCmSap;
  204. return(STATUS_SUCCESS);
  205. }
  206. NDIS_STATUS
  207. PxCmDeRegisterSap(
  208. IN NDIS_HANDLE CallMgrSapContext
  209. )
  210. /*++
  211. Routine Description:
  212. Arguments:
  213. Return Value:
  214. NDIS_STATUS_SUCCESS if everything goes off well right here
  215. NDIS_STATUS_XXXX to indicate any error.
  216. --*/
  217. {
  218. PPX_CM_SAP pCmSap;
  219. PPX_CM_AF pCmAf;
  220. pCmSap = (PPX_CM_SAP)CallMgrSapContext;
  221. //
  222. // BUG 494260
  223. // NDIS should not be invoking this deregister handler at a raised
  224. // IRQL (i.e while holding a spinlock). Bug 494260 documents this
  225. // this issue.
  226. //
  227. // This assert has been commented out to prevent breaks on checked build.
  228. // When 494260 is fixed, this ASSERT should be uncommented.
  229. //
  230. // ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
  231. PXDEBUGP(PXD_LOUD, PXM_CM, ("PxCmDeRegisterSap: CmSap %p\n", pCmSap));
  232. pCmAf = pCmSap->CmAf;
  233. InterlockedExchange((PLONG)&pCmSap->State, PX_SAP_CLOSED);
  234. NdisAcquireSpinLock(&pCmAf->Lock);
  235. RemoveEntryList(&pCmSap->Linkage);
  236. DEREF_CM_AF_LOCKED(pCmAf);
  237. PxFreeCmSap(pCmSap);
  238. //
  239. // Refer comment above
  240. //
  241. //ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
  242. return(STATUS_SUCCESS);
  243. }
  244. NDIS_STATUS
  245. PxCmMakeCall(
  246. IN NDIS_HANDLE CallMgrVcContext,
  247. IN OUT PCO_CALL_PARAMETERS pCallParameters,
  248. IN NDIS_HANDLE NdisPartyHandle OPTIONAL,
  249. OUT PNDIS_HANDLE pCallMgrPartyContext OPTIONAL
  250. )
  251. /*++
  252. Routine Description:
  253. We do not allow a client to make a call!
  254. Arguments:
  255. Return Value:
  256. NDIS_STATUS_SUCCESS if everything goes off well right here
  257. NDIS_STATUS_XXXX to indicate any error.
  258. --*/
  259. {
  260. ASSERT(0);
  261. return(STATUS_SUCCESS);
  262. }
  263. NDIS_STATUS
  264. PxCmCloseCall(
  265. IN NDIS_HANDLE CallMgrVcContext,
  266. IN NDIS_HANDLE CallMgrPartyContext OPTIONAL,
  267. IN PVOID Buffer OPTIONAL,
  268. IN UINT Size OPTIONAL
  269. )
  270. {
  271. PPX_VC pVc;
  272. PPX_CM_AF pCmAf;
  273. NDIS_STATUS Status;
  274. PXDEBUGP(PXD_LOUD, PXM_CM,
  275. ("PxCmCloseCall: VcCtx %x\n", CallMgrVcContext));
  276. GetVcFromCtx(CallMgrVcContext, &pVc);
  277. if (pVc == NULL) {
  278. PXDEBUGP(PXD_WARNING, PXM_CM,
  279. ("PxCmCloseCall: Invalid VcCtx %x!\n", CallMgrVcContext));
  280. return (NDIS_STATUS_SUCCESS);
  281. }
  282. NdisAcquireSpinLock(&pVc->Lock);
  283. pVc->HandoffState = PX_VC_HANDOFF_IDLE;
  284. pVc->CloseFlags |= PX_VC_CL_CLOSE_CALL;
  285. NdisReleaseSpinLock(&pVc->Lock);
  286. NdisCmCloseCallComplete(NDIS_STATUS_SUCCESS,
  287. pVc->CmVcHandle,
  288. NULL);
  289. #ifdef CODELETEVC_FIXED
  290. //
  291. // Evidently the CoCreateVc is unbalanced
  292. // when creating a proxy vc. The call to
  293. // NdisCoDeleteVc will fail because the
  294. // Vc is still active.
  295. // Investigate this with ndis guys!!!!!
  296. //
  297. Status =
  298. NdisCoDeleteVc(pVc->CmVcHandle);
  299. if (Status == NDIS_STATUS_SUCCESS) {
  300. pVc->CmVcHandle = NULL;
  301. }
  302. #endif
  303. NdisAcquireSpinLock(&pVc->Lock);
  304. //
  305. // If the Vc is no longer connected then
  306. // we are waiting for this part of the vc
  307. // to go away before we can cleanup the
  308. // vc with the call manager.
  309. //
  310. if (pVc->Flags & PX_VC_CLEANUP_CM) {
  311. ASSERT(pVc->State == PX_VC_DISCONNECTING);
  312. PxCloseCallWithCm(pVc);
  313. }
  314. pCmAf = pVc->CmAf;
  315. //
  316. // Remove the reference applied when the call
  317. // was dispatched to the client. We do not need
  318. // all of the ref code because of the ref applied
  319. // at entry to this function.
  320. //
  321. pVc->RefCount--;
  322. //
  323. // Deref for ref applied at entry when
  324. // validating the vc
  325. //
  326. DEREF_VC_LOCKED(pVc);
  327. DEREF_CM_AF(pCmAf);
  328. return(NDIS_STATUS_PENDING);
  329. }
  330. VOID
  331. PxCmIncomingCallComplete(
  332. IN NDIS_STATUS Status,
  333. IN NDIS_HANDLE CallMgrVcContext,
  334. IN PCO_CALL_PARAMETERS pCallParameters
  335. )
  336. {
  337. PPX_VC pVc;
  338. PXDEBUGP(PXD_LOUD, PXM_CM,
  339. ("PxCmIncomingCallComplete: VcCtx %x\n", CallMgrVcContext));
  340. GetVcFromCtx(CallMgrVcContext, &pVc);
  341. if (pVc == NULL) {
  342. PXDEBUGP(PXD_WARNING, PXM_CM,
  343. ("PxCmIncomingCallComplete: Invalid VcCtx %x!\n",
  344. CallMgrVcContext));
  345. return;
  346. }
  347. NdisAcquireSpinLock(&pVc->Lock);
  348. PXDEBUGP(PXD_LOUD, PXM_CM,
  349. ("PxCmIncomingCallComplete: Vc %p, Status %x\n",
  350. pVc, Status));
  351. PxSignal(&pVc->Block, Status);
  352. //
  353. // remove the ref applied when we mapped
  354. // the vcctx to the vc
  355. //
  356. DEREF_VC_LOCKED(pVc);
  357. }
  358. NDIS_STATUS
  359. PxCmAddParty(
  360. IN NDIS_HANDLE CallMgrVcContext,
  361. IN OUT PCO_CALL_PARAMETERS pCallParameters,
  362. IN NDIS_HANDLE NdisPartyHandle,
  363. OUT PNDIS_HANDLE pCallMgrPartyContext
  364. )
  365. /*++
  366. Routine Description:
  367. We do not allow a client to add a party to a vc!
  368. Arguments:
  369. Return Value:
  370. NDIS_STATUS_SUCCESS if everything goes off well right here
  371. NDIS_STATUS_XXXX to indicate any error.
  372. --*/
  373. {
  374. ASSERT(0);
  375. return(STATUS_SUCCESS);
  376. }
  377. NDIS_STATUS
  378. PxCmDropParty(
  379. IN NDIS_HANDLE CallMgrPartyContext,
  380. IN PVOID Buffer OPTIONAL,
  381. IN UINT Size OPTIONAL
  382. )
  383. /*++
  384. Routine Description:
  385. We do not allow a client to drop a party on a vc!
  386. Arguments:
  387. Return Value:
  388. NDIS_STATUS_SUCCESS if everything goes off well right here
  389. NDIS_STATUS_XXXX to indicate any error.
  390. --*/
  391. {
  392. ASSERT(0);
  393. return(STATUS_SUCCESS);
  394. }
  395. VOID
  396. PxCmActivateVcComplete(
  397. IN NDIS_STATUS Status,
  398. IN NDIS_HANDLE CallMgrVcContext,
  399. IN PCO_CALL_PARAMETERS pCallParameters)
  400. /*++
  401. Routine Description:
  402. The vc has already been activate by the underlying
  403. call manager/miniport!
  404. Arguments:
  405. Return Value:
  406. NDIS_STATUS_SUCCESS if everything goes off well right here
  407. NDIS_STATUS_XXXX to indicate any error.
  408. --*/
  409. {
  410. ASSERT(0);
  411. }
  412. VOID
  413. PxCmDeActivateVcComplete(
  414. IN NDIS_STATUS Status,
  415. IN NDIS_HANDLE CallMgrVcContext
  416. )
  417. /*++
  418. Routine Description:
  419. The vc is never deactivated by our call manager!
  420. Arguments:
  421. Return Value:
  422. NDIS_STATUS_SUCCESS if everything goes off well right here
  423. NDIS_STATUS_XXXX to indicate any error.
  424. --*/
  425. {
  426. ASSERT(0);
  427. }
  428. NDIS_STATUS
  429. PxCmModifyCallQos(
  430. IN NDIS_HANDLE CallMgrVcContext,
  431. IN PCO_CALL_PARAMETERS pCallParameters
  432. )
  433. /*++
  434. Routine Description:
  435. Not sure what to do here right now!
  436. ToDo!!!!!!!!!!
  437. Arguments:
  438. Return Value:
  439. NDIS_STATUS_SUCCESS if everything goes off well right here
  440. NDIS_STATUS_XXXX to indicate any error.
  441. --*/
  442. {
  443. return(STATUS_SUCCESS);
  444. }
  445. NDIS_STATUS
  446. PxCmRequest(
  447. IN NDIS_HANDLE ProtocolAfContext,
  448. IN NDIS_HANDLE ProtocolVcContext OPTIONAL,
  449. IN NDIS_HANDLE ProtocolPartyContext OPTIONAL,
  450. IN OUT PNDIS_REQUEST NdisRequest
  451. )
  452. /*++
  453. Routine Description:
  454. We will handle requests from the clients and pass them down
  455. to the underlying call manager/miniport if needed.
  456. Arguments:
  457. Return Value:
  458. NDIS_STATUS_SUCCESS if everything goes off well right here
  459. NDIS_STATUS_XXXX to indicate any error.
  460. --*/
  461. {
  462. return(STATUS_SUCCESS);
  463. }
  464. VOID
  465. PxCmRequestComplete(
  466. IN NDIS_STATUS Status,
  467. IN NDIS_HANDLE ProtocolAfContext,
  468. IN NDIS_HANDLE ProtocolVcContext, // Optional
  469. IN NDIS_HANDLE ProtocolPartyContext, // Optional
  470. IN PNDIS_REQUEST NdisRequest
  471. )
  472. /*++
  473. Routine Description:
  474. Called by the client upon completion of any requests
  475. that we have passed up to it. If this request needed to
  476. be completed synchronously (status matters) then we will
  477. signal completion and let the calling routine free the
  478. memory. If this could complete asynchronously then we
  479. just free the memory here.
  480. Arguments:
  481. Return Value:
  482. NDIS_STATUS_SUCCESS if everything goes off well right here
  483. NDIS_STATUS_XXXX to indicate any error.
  484. --*/
  485. {
  486. PPX_REQUEST pProxyRequest;
  487. PPX_CM_AF pCmAf;
  488. PPX_VC pVc;
  489. pCmAf = (PPX_CM_AF)ProtocolAfContext;
  490. pVc = (PPX_VC)ProtocolVcContext;
  491. PXDEBUGP(PXD_INFO, PXM_CM, ("PxCmRequestComplete: CmAf %p, Vc %p\n", pCmAf, pVc));
  492. pProxyRequest = CONTAINING_RECORD(NdisRequest, PX_REQUEST, NdisRequest);
  493. if (pProxyRequest->Flags & PX_REQ_ASYNC) {
  494. pProxyRequest->Flags &= ~PX_REQ_ASYNC;
  495. PxFreeMem(pProxyRequest);
  496. DEREF_CM_AF(pCmAf);
  497. } else {
  498. PxSignal(&pProxyRequest->Block, Status);
  499. }
  500. }