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.

318 lines
6.3 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation, 1992 - 1999
  3. Module Name:
  4. autohand.cxx
  5. Abstract:
  6. This module implements the autohandle functions call by the compiler
  7. generated stubs.
  8. Author:
  9. Steven Zeck (stevez) 03/10/92
  10. Kamen Moutafov (KamenM) Feb 2000 - add support for multiple transfer syntaxes
  11. --*/
  12. #include <rpc.h>
  13. #include <rpcdcep.h>
  14. #ifdef __cplusplus
  15. extern "C" {
  16. #endif
  17. #include <rpcnsi.h>
  18. #include <rpcnsip.h>
  19. #ifdef __cplusplus
  20. }
  21. #endif
  22. typedef RPC_STATUS
  23. (RPC_ENTRY *RPC_BIND)
  24. (
  25. IN PRPC_MESSAGE Message
  26. );
  27. RPC_STATUS
  28. RpcpNsGetBuffer(
  29. IN PRPC_MESSAGE Message,
  30. RPC_BIND BindFn
  31. );
  32. // Interface can be only RPC_CLIENT_INTERFACE
  33. inline BOOL DoesInterfaceSupportMultipleTransferSyntaxes(void *Interface)
  34. {
  35. // the client and server interface have the same layout - we can just
  36. // use one of them
  37. RPC_CLIENT_INTERFACE *ClientInterface = (RPC_CLIENT_INTERFACE *)Interface;
  38. if (ClientInterface->Length == NT351_INTERFACE_SIZE)
  39. return FALSE;
  40. return (ClientInterface->Flags & RPCFLG_HAS_MULTI_SYNTAXES);
  41. }
  42. RPC_STATUS RPC_ENTRY
  43. I_RpcNsGetBuffer(
  44. IN PRPC_MESSAGE Message
  45. )
  46. /*++
  47. Routine Description:
  48. Auto bind to a given interface.
  49. Arguments:
  50. Message - describes the interface that we want to auto bind to.
  51. Returns:
  52. RPC_S_OK, RPC_S_CALL_FAILED_DNE, I_RpcGetBuffer()
  53. --*/
  54. {
  55. if (!DoesInterfaceSupportMultipleTransferSyntaxes(Message->RpcInterfaceInformation))
  56. Message->ImportContext = 0;
  57. return RpcpNsGetBuffer(Message, I_RpcGetBuffer);
  58. }
  59. extern "C"
  60. {
  61. RPC_STATUS RPC_ENTRY
  62. I_RpcNsNegotiateTransferSyntax(
  63. IN PRPC_MESSAGE Message
  64. );
  65. }; // extern "C"
  66. RPC_STATUS RPC_ENTRY
  67. I_RpcNsNegotiateTransferSyntax(
  68. IN PRPC_MESSAGE Message
  69. )
  70. /*++
  71. Routine Description:
  72. Auto bind to a given interface.
  73. Arguments:
  74. Message - describes the interface that we want to auto bind to.
  75. Returns:
  76. RPC_S_OK, RPC_S_CALL_FAILED_DNE, I_RpcGetBuffer()
  77. --*/
  78. {
  79. Message->ImportContext = 0;
  80. return RpcpNsGetBuffer(Message, I_RpcNegotiateTransferSyntax);
  81. }
  82. RPC_STATUS
  83. RpcpNsGetBuffer(
  84. IN PRPC_MESSAGE Message,
  85. RPC_BIND BindFn
  86. )
  87. /*++
  88. Routine Description:
  89. Auto bind to a given interface.
  90. Arguments:
  91. Message - describes the interface that we want to auto bind to.
  92. Returns:
  93. RPC_S_OK or error
  94. --*/
  95. {
  96. RPC_STATUS status;
  97. PRPC_IMPORT_CONTEXT_P Import;
  98. int fSetAge = 0;
  99. // If there already is a handle, use it directly.
  100. if (Message->Handle)
  101. return(BindFn(Message));
  102. Message->ImportContext = 0;
  103. for (int cTry = 0; cTry < 2; cTry++)
  104. {
  105. status = RpcNsBindingImportBegin(RPC_C_NS_SYNTAX_DEFAULT, 0,
  106. Message->RpcInterfaceInformation, 0, &Message->ImportContext);
  107. Import = (PRPC_IMPORT_CONTEXT_P) Message->ImportContext;
  108. if (status)
  109. break;
  110. // This will cause some Zecky Magic
  111. // Also note that naively one might move this ExpAge to
  112. // after the first lookup failed time- that is a bobo
  113. if (fSetAge)
  114. status = RpcNsMgmtHandleSetExpAge (Message->ImportContext, 0);
  115. // If we found no bindings last time, tell the locator
  116. // to look on the net.
  117. // For each handle returned by import, try using it with I_RpcGetBuffer
  118. // function until success or no more import handles.
  119. while(RpcNsBindingImportNext(Import, &Import->ProposedHandle)
  120. == RPC_S_OK)
  121. {
  122. Message->Handle = Import->ProposedHandle;
  123. if (BindFn(Message) == RPC_S_OK)
  124. return(RPC_S_OK);
  125. RpcBindingFree(&Import->ProposedHandle);
  126. }
  127. fSetAge = 1;
  128. RpcNsBindingImportDone(&Message->ImportContext);
  129. }
  130. if (status == RPC_S_NAME_SERVICE_UNAVAILABLE ||
  131. status == RPC_S_OUT_OF_MEMORY ||
  132. status == RPC_S_OUT_OF_RESOURCES)
  133. return(status);
  134. return(RPC_S_CALL_FAILED_DNE);
  135. }
  136. RPC_STATUS RPC_ENTRY
  137. I_RpcNsSendReceive(
  138. IN PRPC_MESSAGE Message,
  139. OUT RPC_BINDING_HANDLE * Handle
  140. )
  141. /*++
  142. Routine Description:
  143. Make a call on a RPC server. If the call fails continue looking for
  144. servers to bind to. This is only needed for protocols
  145. which don't allocate the connection at I_RpcGetBuffer time.
  146. Arguments:
  147. Message - describes the interface that we want to Call. The
  148. ImportContext field contains the active lookup handle, if any.
  149. Handle - returns the binding handle used on the successfull call.
  150. Returns:
  151. RPC_S_CALL_FAILED_DNE, I_RpcSendReceive()
  152. --*/
  153. {
  154. RPC_STATUS status;
  155. PRPC_IMPORT_CONTEXT_P Import;
  156. Import = (PRPC_IMPORT_CONTEXT_P) Message->ImportContext;
  157. while ((status = I_RpcSendReceive(Message)) != RPC_S_OK && Import)
  158. {
  159. RpcBindingFree(&Import->ProposedHandle);
  160. // The call failed, try the next binding handle
  161. while(RpcNsBindingImportNext(Import, &Import->ProposedHandle)
  162. == RPC_S_OK)
  163. {
  164. Message->Handle = Import->ProposedHandle;
  165. I_RpcReBindBuffer(Message);
  166. continue;
  167. }
  168. I_RpcFreeBuffer(Message);
  169. status = RPC_S_CALL_FAILED_DNE;
  170. }
  171. if (Import)
  172. {
  173. *Handle = Import->ProposedHandle;
  174. RpcNsBindingImportDone(&Message->ImportContext);
  175. }
  176. if (status)
  177. *Handle = 0;
  178. return(status);
  179. }
  180. void RPC_ENTRY
  181. I_RpcNsRaiseException(
  182. IN PRPC_MESSAGE Message,
  183. IN RPC_STATUS Status
  184. )
  185. /*++
  186. Routine Description:
  187. Raise an Exception for an autobind interface. We simply cleanup any
  188. open import context and raise the exception.
  189. Arguments:
  190. Message - continas the import context, if any.
  191. --*/
  192. {
  193. RpcNsBindingImportDone(&Message->ImportContext);
  194. RpcRaiseException(Status);
  195. }
  196. // BUG BUG implement this is the runtime.
  197. RPC_STATUS RPC_ENTRY
  198. I_RpcReBindBuffer(
  199. IN PRPC_MESSAGE Message
  200. )
  201. {
  202. (void __RPC_FAR *) Message;
  203. RpcRaiseException(RPC_S_INTERNAL_ERROR);
  204. return(0);
  205. }