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.

258 lines
8.9 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1990 - 1999
  6. //
  7. // File: ProtBind.cxx
  8. //
  9. //--------------------------------------------------------------------------
  10. /* --------------------------------------------------------------------
  11. File: ProtBind.cxx
  12. Description:
  13. The implementation of the classes that support the binding process for
  14. connection oriented and local.
  15. History :
  16. kamenm 10-01-00 Cloned from other files with a face lift and few stitches added
  17. -------------------------------------------------------------------- */
  18. #include <precomp.hxx>
  19. #include <ProtBind.hxx>
  20. // the following lookup table uses the least significant byte of
  21. // SyntaxGUID.Data4[0]. It is 0xF for NDR20, 0x3 for NDR64, and
  22. // 0x5 for NDRTest
  23. const int SyntaxBindingCapabilitiesLookup[0x10] = {
  24. MTSyntaxBinding::SyntaxBindingCapabilityInvalid, // 0
  25. MTSyntaxBinding::SyntaxBindingCapabilityInvalid, // 1
  26. MTSyntaxBinding::SyntaxBindingCapabilityInvalid, // 2
  27. MTSyntaxBinding::SyntaxBindingCapabilityNDR64, // 3 - NDR64
  28. MTSyntaxBinding::SyntaxBindingCapabilityInvalid, // 4
  29. MTSyntaxBinding::SyntaxBindingCapabilityNDRTest, // 5 - NDRTest
  30. MTSyntaxBinding::SyntaxBindingCapabilityInvalid, // 6
  31. MTSyntaxBinding::SyntaxBindingCapabilityInvalid, // 7
  32. MTSyntaxBinding::SyntaxBindingCapabilityInvalid, // 8
  33. MTSyntaxBinding::SyntaxBindingCapabilityInvalid, // 9
  34. MTSyntaxBinding::SyntaxBindingCapabilityInvalid, // 0xA
  35. MTSyntaxBinding::SyntaxBindingCapabilityInvalid, // 0xB
  36. MTSyntaxBinding::SyntaxBindingCapabilityInvalid, // 0xC
  37. MTSyntaxBinding::SyntaxBindingCapabilityInvalid, // 0xD
  38. MTSyntaxBinding::SyntaxBindingCapabilityInvalid, // 0xE
  39. MTSyntaxBinding::SyntaxBindingCapabilityNDR20 // 0xF - NDR20
  40. };
  41. RPC_STATUS
  42. MTSyntaxBinding::FindOrCreateBinding (
  43. IN PRPC_CLIENT_INTERFACE RpcInterfaceInformation,
  44. IN RPC_MESSAGE *Message,
  45. IN SIMPLE_DICT *BindingsDict,
  46. IN CreateBindingFn CreateBinding,
  47. IN CheckBindingForDestructionFn CheckBinding, OPTIONAL
  48. IN void *CallbackContext, OPTIONAL
  49. OUT int *NumberOfBindings,
  50. IN OUT MTSyntaxBinding *BindingsForThisInterface[],
  51. IN OUT BOOL BindingCreated[]
  52. )
  53. /*++
  54. Routine Description:
  55. This method gets called to find the bindings (a dictionary
  56. entry) corresponding to the specified rpc interface information.
  57. The caller of this routine is responsible for synchronization
  58. Arguments:
  59. RpcInterfaceInformation - Supplies the interface information for
  60. which we are looking for an osf binding object.
  61. Message - supplies the RPC_MESSAGE for this call
  62. BindingsDict - the dictionary of available bindings (and where
  63. to put created bindings)
  64. CreateBinding - a callback function for creating a binding
  65. CheckBinding - a callback function to detect stale bindings and
  66. to destroy them.
  67. CallbackContext - an optional context to be supplied to the CheckBinding
  68. callback.
  69. NumberOfBindings - an out parameter that will return the number
  70. of retrieved bindings
  71. BindingsForThisInterface - a caller supplied array where the
  72. found bindings will be placed.
  73. BindingCreated - a caller supplied array of the same size as
  74. BindingsForThisInterface where this function will record
  75. which binding was created and which was found.
  76. Return Value:
  77. RPC_S_OK for success, other for failure
  78. --*/
  79. {
  80. MTSyntaxBinding *Binding;
  81. DictionaryCursor cursor;
  82. unsigned int i;
  83. ULONG NumberOfTransferSyntaxes;
  84. MIDL_SYNTAX_INFO *SyntaxInfoArray;
  85. int NextBindingToBeReturned;
  86. RPC_STATUS Status;
  87. BOOL fHasMultiSyntaxes;
  88. TRANSFER_SYNTAX_STUB_INFO *CurrentTransferInfo;
  89. int ClientPreferredTransferSyntax;
  90. MTSyntaxBinding *CurrentBinding;
  91. int CapabilitiesBitmap;
  92. unsigned char CurrentTransferInfoLookupValue;
  93. int CurrentCapability;
  94. BOOL IsBindingDestroyed;
  95. if ((RpcInterfaceInformation->Length != sizeof(RPC_CLIENT_INTERFACE)) &&
  96. (RpcInterfaceInformation->Length != NT351_INTERFACE_SIZE))
  97. {
  98. return RPC_S_UNKNOWN_IF;
  99. }
  100. if (DoesInterfaceSupportMultipleTransferSyntaxes(RpcInterfaceInformation))
  101. {
  102. Status = NdrClientGetSupportedSyntaxes (RpcInterfaceInformation,
  103. &NumberOfTransferSyntaxes, &SyntaxInfoArray);
  104. if (Status != RPC_S_OK)
  105. return Status;
  106. ASSERT(NumberOfTransferSyntaxes > 0);
  107. ASSERT(SyntaxInfoArray != NULL);
  108. fHasMultiSyntaxes = TRUE;
  109. }
  110. else
  111. {
  112. fHasMultiSyntaxes = FALSE;
  113. NumberOfTransferSyntaxes = 1;
  114. }
  115. // build the capabilities bitmap
  116. CapabilitiesBitmap = 0;
  117. for (i = 0; i < NumberOfTransferSyntaxes; i ++)
  118. {
  119. if (fHasMultiSyntaxes)
  120. {
  121. CurrentTransferInfo
  122. = (TRANSFER_SYNTAX_STUB_INFO *)&SyntaxInfoArray[i].TransferSyntax;
  123. }
  124. else
  125. {
  126. CurrentTransferInfo
  127. = (TRANSFER_SYNTAX_STUB_INFO *)&RpcInterfaceInformation->TransferSyntax;
  128. }
  129. CurrentTransferInfoLookupValue = CurrentTransferInfo->TransferSyntax.SyntaxGUID.Data4[0] & 0xF;
  130. CurrentCapability = SyntaxBindingCapabilitiesLookup[CurrentTransferInfoLookupValue];
  131. ASSERT(CurrentCapability != MTSyntaxBinding::SyntaxBindingCapabilityInvalid);
  132. if (CurrentCapability == MTSyntaxBinding::SyntaxBindingCapabilityInvalid)
  133. return RPC_S_UNSUPPORTED_TRANS_SYN;
  134. CapabilitiesBitmap |= CurrentCapability;
  135. }
  136. // if we create a binding here, we must also properly link it to the
  137. // other bindings that differ only by transfer syntax. We rely on the fact
  138. // that the stubs will always return multiple transfer syntaxes in the same
  139. // order. Therefore, we add them one by one, and if we fail towards the end
  140. // we leave the already added entries there. The next time we come, we
  141. // will try to continue off where we left
  142. NextBindingToBeReturned = 0;
  143. CurrentBinding = 0;
  144. for (i = 0; i < NumberOfTransferSyntaxes; i ++)
  145. {
  146. //
  147. // First we search for an existing presentation context
  148. // corresponding to the specified interface information. Otherwise,
  149. // we create a new presentation context.
  150. //
  151. if (fHasMultiSyntaxes)
  152. {
  153. CurrentTransferInfo
  154. = (TRANSFER_SYNTAX_STUB_INFO *)&SyntaxInfoArray[i].TransferSyntax;
  155. }
  156. else
  157. {
  158. CurrentTransferInfo
  159. = (TRANSFER_SYNTAX_STUB_INFO *)&RpcInterfaceInformation->TransferSyntax;
  160. }
  161. BindingsDict->Reset(cursor);
  162. while ((Binding = (MTSyntaxBinding *)BindingsDict->Next(cursor)) != 0)
  163. {
  164. if (CheckBinding)
  165. {
  166. IsBindingDestroyed = CheckBinding(Binding, CallbackContext);
  167. if (IsBindingDestroyed)
  168. continue;
  169. }
  170. if (Binding->CompareWithRpcInterfaceInformation(&RpcInterfaceInformation->InterfaceId,
  171. CurrentTransferInfo, CapabilitiesBitmap) == 0)
  172. {
  173. BindingCreated[NextBindingToBeReturned] = FALSE;
  174. CurrentBinding = Binding;
  175. goto StoreResultAndLookForNextTransferSyntax;
  176. }
  177. }
  178. // if we are here, we haven't found any bindings for this transfer syntax -
  179. // create some
  180. Binding = CreateBinding(&RpcInterfaceInformation->InterfaceId,
  181. CurrentTransferInfo, CapabilitiesBitmap);
  182. if (Binding == 0)
  183. {
  184. *NumberOfBindings = i;
  185. return(RPC_S_OUT_OF_MEMORY);
  186. }
  187. Binding->SetPresentationContext(BindingsDict->Insert(Binding));
  188. if (Binding->GetPresentationContext() == -1)
  189. {
  190. delete Binding;
  191. *NumberOfBindings = i;
  192. return RPC_S_OUT_OF_MEMORY;
  193. }
  194. if (CurrentBinding != 0)
  195. CurrentBinding->SetNextBinding(Binding);
  196. CurrentBinding = Binding;
  197. // the first transfer syntax info is marked as the list start
  198. // this helps us figure out where the list starts later on
  199. if (i == 0)
  200. Binding->TransferSyntaxIsListStart();
  201. BindingCreated[NextBindingToBeReturned] = TRUE;
  202. StoreResultAndLookForNextTransferSyntax:
  203. // return the newly created binding to our caller
  204. BindingsForThisInterface[NextBindingToBeReturned] = Binding;
  205. NextBindingToBeReturned ++;
  206. }
  207. *NumberOfBindings = NumberOfTransferSyntaxes;
  208. return RPC_S_OK;
  209. }