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.

223 lines
5.2 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. connreq.c
  5. Abstract:
  6. This module contains the connection request handling functions
  7. Author:
  8. Stefan Solomon 04/19/1995
  9. Revision History:
  10. --*/
  11. #include "precomp.h"
  12. #pragma hdrstop
  13. VOID
  14. DoConnectInterface(PVOID InterfaceIndex);
  15. /*++
  16. Function: ForwarderNotification
  17. Descr: This is invoked in the router manager worker thread context
  18. following a notification from the forwarder. It dequeues all
  19. connection requests and calls DDM for each one of them.
  20. --*/
  21. VOID
  22. ForwarderNotification(VOID)
  23. {
  24. DWORD rc;
  25. PICB icbp;
  26. HANDLE hDIMInterface;
  27. ULONG nBytes = 0;
  28. // Check if the signaled notification is valid or an error condition
  29. rc = FwGetNotificationResult(&ConnReqOverlapped, &nBytes);
  30. ACQUIRE_DATABASE_LOCK;
  31. if (RouterOperState == OPER_STATE_UP) {
  32. if(rc == NO_ERROR) {
  33. if (((icbp = GetInterfaceByIndex(ConnRequest->IfIndex)) != NULL)
  34. && !icbp->ConnectionRequestPending) {
  35. IF_LOG (EVENTLOG_INFORMATION_TYPE) {
  36. WCHAR ByteCount[16];
  37. LPWSTR StrArray[2]= {icbp->InterfaceNamep, ByteCount};
  38. _ultow (nBytes-FIELD_OFFSET (FW_DIAL_REQUEST, Packet),
  39. ByteCount, 10);
  40. RouterLogInformationDataW (RMEventLogHdl,
  41. ROUTERLOG_IPX_DEMAND_DIAL_PACKET,
  42. 2, StrArray,
  43. nBytes-FIELD_OFFSET (FW_DIAL_REQUEST, Packet),
  44. &ConnRequest->Packet[0]);
  45. }
  46. icbp->ConnectionRequestPending = TRUE;
  47. if(RtlQueueWorkItem(DoConnectInterface, (PVOID)ConnRequest, 0) == STATUS_SUCCESS) {
  48. // work item queued
  49. WorkItemsPendingCounter++;
  50. }
  51. else
  52. {
  53. SS_ASSERT(FALSE);
  54. }
  55. ConnRequest = (PFW_DIAL_REQUEST)GlobalAlloc (GPTR, DIAL_REQUEST_BUFFER_SIZE);
  56. if (ConnRequest==NULL) {
  57. rc = GetLastError ();
  58. Trace(CONNREQ_TRACE, "Cannot allocate Connecttion Request buffer, rc = %d\n", rc);
  59. }
  60. }
  61. }
  62. else {
  63. Trace(CONNREQ_TRACE, "Error %d in FwGetNotificationResult\n", rc);
  64. }
  65. // now repost the IOCtl
  66. if (ConnRequest!=NULL) {
  67. rc = FwNotifyConnectionRequest(ConnRequest,
  68. DIAL_REQUEST_BUFFER_SIZE,
  69. &ConnReqOverlapped);
  70. if(rc != NO_ERROR) {
  71. GlobalFree (ConnRequest);
  72. ConnRequest = NULL;
  73. Trace(CONNREQ_TRACE, "Cannot repost the FwNotifyConnecttionRequest, rc = %d\n", rc);
  74. }
  75. }
  76. }
  77. else {
  78. GlobalFree (ConnRequest);
  79. }
  80. RELEASE_DATABASE_LOCK;
  81. return;
  82. }
  83. VOID
  84. DoConnectInterface(PVOID param)
  85. {
  86. #define connRequest ((PFW_DIAL_REQUEST)param)
  87. PICB icbp;
  88. HANDLE hDIMInterface;
  89. DWORD rc;
  90. ACQUIRE_DATABASE_LOCK;
  91. if(RouterOperState != OPER_STATE_UP) {
  92. goto Exit;
  93. }
  94. if ((icbp = GetInterfaceByIndex(connRequest->IfIndex)) == NULL){
  95. goto Exit;
  96. }
  97. hDIMInterface = icbp->hDIMInterface;
  98. RELEASE_DATABASE_LOCK;
  99. rc = (*ConnectInterface)(hDIMInterface, PID_IPX);
  100. ACQUIRE_DATABASE_LOCK;
  101. if((icbp = GetInterfaceByIndex(connRequest->IfIndex)) == NULL) {
  102. goto Exit;
  103. }
  104. if (rc != PENDING) {
  105. icbp->ConnectionRequestPending = FALSE;
  106. // check if we failed right away
  107. if(rc != NO_ERROR) {
  108. // failed to request connection
  109. Trace(CONNREQ_TRACE, "DoConnectInterface: ConnectInterface failed with rc= 0x%x for if # %d\n",
  110. rc, connRequest->IfIndex);
  111. FwConnectionRequestFailed(connRequest->IfIndex);
  112. }
  113. else
  114. {
  115. // Connection request has been succesfull right away and
  116. // we will get notified via the connected adapter
  117. Trace(CONNREQ_TRACE, "DoConnectInterface: ConnectInterface successful -> CONNECTED for if # %d\n",
  118. connRequest->IfIndex);
  119. }
  120. }
  121. else
  122. {
  123. // a connection request is pending
  124. Trace(CONNREQ_TRACE, "DoConnectInterface: Connection request PENDING for if # %d\n",
  125. connRequest->IfIndex);
  126. }
  127. Exit:
  128. GlobalFree (connRequest);
  129. WorkItemsPendingCounter--;
  130. RELEASE_DATABASE_LOCK;
  131. #undef connRequest
  132. }
  133. DWORD
  134. RoutingProtocolConnectionRequest(ULONG ProtocolId,
  135. ULONG InterfaceIndex)
  136. {
  137. PICB icbp;
  138. HANDLE hDIMInterface;
  139. DWORD rc;
  140. ACQUIRE_DATABASE_LOCK;
  141. if((icbp = GetInterfaceByIndex(InterfaceIndex)) == NULL) {
  142. RELEASE_DATABASE_LOCK;
  143. return ERROR_CAN_NOT_COMPLETE;
  144. }
  145. if (icbp->ConnectionRequestPending) {
  146. RELEASE_DATABASE_LOCK;
  147. return PENDING;
  148. }
  149. // ask DDM to make a connection for this interface
  150. hDIMInterface = icbp->hDIMInterface;
  151. icbp->ConnectionRequestPending = TRUE;
  152. RELEASE_DATABASE_LOCK;
  153. rc = (*ConnectInterface)(hDIMInterface, PID_IPX);
  154. ACQUIRE_DATABASE_LOCK;
  155. if((icbp = GetInterfaceByIndex(InterfaceIndex)) == NULL) {
  156. RELEASE_DATABASE_LOCK;
  157. return ERROR_CAN_NOT_COMPLETE;
  158. }
  159. if (rc != PENDING)
  160. icbp->ConnectionRequestPending = FALSE;
  161. RELEASE_DATABASE_LOCK;
  162. return rc;
  163. }