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.

230 lines
7.8 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. OUT int *NumberOfBindings,
  48. IN OUT MTSyntaxBinding *BindingsForThisInterface[],
  49. IN OUT BOOL BindingCreated[]
  50. )
  51. /*++
  52. Routine Description:
  53. This method gets called to find the bindings (a dictionary
  54. entry) corresponding to the specified rpc interface information.
  55. The caller of this routine is responsible for synchronization
  56. Arguments:
  57. RpcInterfaceInformation - Supplies the interface information for
  58. which we are looking for an osf binding object.
  59. Message - supplies the RPC_MESSAGE for this call
  60. NumberOfBindings - an out parameter that will return the number
  61. of retrieved bindings
  62. BindingsForThisInterface - a caller supplied array where the
  63. found bindings will be placed.
  64. Return Value:
  65. RPC_S_OK for success, other for failure
  66. --*/
  67. {
  68. MTSyntaxBinding *Binding;
  69. DictionaryCursor cursor;
  70. unsigned int i;
  71. ULONG NumberOfTransferSyntaxes;
  72. MIDL_SYNTAX_INFO *SyntaxInfoArray;
  73. int NextBindingToBeReturned;
  74. RPC_STATUS Status;
  75. BOOL fHasMultiSyntaxes;
  76. TRANSFER_SYNTAX_STUB_INFO *CurrentTransferInfo;
  77. int ClientPreferredTransferSyntax;
  78. MTSyntaxBinding *CurrentBinding;
  79. int CapabilitiesBitmap;
  80. unsigned char CurrentTransferInfoLookupValue;
  81. int CurrentCapability;
  82. if ((RpcInterfaceInformation->Length != sizeof(RPC_CLIENT_INTERFACE)) &&
  83. (RpcInterfaceInformation->Length != NT351_INTERFACE_SIZE))
  84. {
  85. return RPC_S_UNKNOWN_IF;
  86. }
  87. if (DoesInterfaceSupportMultipleTransferSyntaxes(RpcInterfaceInformation))
  88. {
  89. Status = NdrClientGetSupportedSyntaxes (RpcInterfaceInformation,
  90. &NumberOfTransferSyntaxes, &SyntaxInfoArray);
  91. if (Status != RPC_S_OK)
  92. return Status;
  93. ASSERT(NumberOfTransferSyntaxes > 0);
  94. ASSERT(SyntaxInfoArray != NULL);
  95. fHasMultiSyntaxes = TRUE;
  96. }
  97. else
  98. {
  99. fHasMultiSyntaxes = FALSE;
  100. NumberOfTransferSyntaxes = 1;
  101. }
  102. // build the capabilities bitmap
  103. CapabilitiesBitmap = 0;
  104. for (i = 0; i < NumberOfTransferSyntaxes; i ++)
  105. {
  106. if (fHasMultiSyntaxes)
  107. {
  108. CurrentTransferInfo
  109. = (TRANSFER_SYNTAX_STUB_INFO *)&SyntaxInfoArray[i].TransferSyntax;
  110. }
  111. else
  112. {
  113. CurrentTransferInfo
  114. = (TRANSFER_SYNTAX_STUB_INFO *)&RpcInterfaceInformation->TransferSyntax;
  115. }
  116. CurrentTransferInfoLookupValue = CurrentTransferInfo->TransferSyntax.SyntaxGUID.Data4[0] & 0xF;
  117. CurrentCapability = SyntaxBindingCapabilitiesLookup[CurrentTransferInfoLookupValue];
  118. ASSERT(CurrentCapability != MTSyntaxBinding::SyntaxBindingCapabilityInvalid);
  119. if (CurrentCapability == MTSyntaxBinding::SyntaxBindingCapabilityInvalid)
  120. return RPC_S_UNSUPPORTED_TRANS_SYN;
  121. CapabilitiesBitmap |= CurrentCapability;
  122. }
  123. // if we create a binding here, we must also properly link it to the
  124. // other bindings that differ only by transfer syntax. We rely on the fact
  125. // that the stubs will always return multiple transfer syntaxes in the same
  126. // order. Therefore, we add them one by one, and if we fail towards the end
  127. // we leave the already added entries there. The next time we come, we
  128. // will try to continue off where we left
  129. NextBindingToBeReturned = 0;
  130. CurrentBinding = 0;
  131. for (i = 0; i < NumberOfTransferSyntaxes; i ++)
  132. {
  133. //
  134. // First we search for an existing presentation context
  135. // corresponding to the specified interface information. Otherwise,
  136. // we create a new presentation context.
  137. //
  138. if (fHasMultiSyntaxes)
  139. {
  140. CurrentTransferInfo
  141. = (TRANSFER_SYNTAX_STUB_INFO *)&SyntaxInfoArray[i].TransferSyntax;
  142. }
  143. else
  144. {
  145. CurrentTransferInfo
  146. = (TRANSFER_SYNTAX_STUB_INFO *)&RpcInterfaceInformation->TransferSyntax;
  147. }
  148. BindingsDict->Reset(cursor);
  149. while ((Binding = (MTSyntaxBinding *)BindingsDict->Next(cursor)) != 0)
  150. {
  151. if (Binding->CompareWithRpcInterfaceInformation(&RpcInterfaceInformation->InterfaceId,
  152. CurrentTransferInfo, CapabilitiesBitmap) == 0)
  153. {
  154. BindingCreated[NextBindingToBeReturned] = FALSE;
  155. CurrentBinding = Binding;
  156. goto StoreResultAndLookForNextTransferSyntax;
  157. }
  158. }
  159. // if we are here, we haven't found any bindings for this transfer syntax -
  160. // create some
  161. Binding = CreateBinding(&RpcInterfaceInformation->InterfaceId,
  162. CurrentTransferInfo, CapabilitiesBitmap);
  163. if (Binding == 0)
  164. {
  165. *NumberOfBindings = i;
  166. return(RPC_S_OUT_OF_MEMORY);
  167. }
  168. Binding->SetPresentationContext(BindingsDict->Insert(Binding));
  169. if (Binding->GetPresentationContext() == -1)
  170. {
  171. delete Binding;
  172. *NumberOfBindings = i;
  173. return RPC_S_OUT_OF_MEMORY;
  174. }
  175. if (CurrentBinding != 0)
  176. CurrentBinding->SetNextBinding(Binding);
  177. CurrentBinding = Binding;
  178. // the first transfer syntax info is marked as the list start
  179. // this helps us figure out where the list starts later on
  180. if (i == 0)
  181. Binding->TransferSyntaxIsListStart();
  182. BindingCreated[NextBindingToBeReturned] = TRUE;
  183. StoreResultAndLookForNextTransferSyntax:
  184. // return the newly created binding to our caller
  185. BindingsForThisInterface[NextBindingToBeReturned] = Binding;
  186. NextBindingToBeReturned ++;
  187. }
  188. *NumberOfBindings = NumberOfTransferSyntaxes;
  189. return RPC_S_OK;
  190. }