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.

2535 lines
54 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation, 1991 - 1999
  3. Module Name:
  4. osfclnt.hxx
  5. Abstract:
  6. This file contains the client side classes for the OSF connection
  7. oriented RPC protocol engine.
  8. Author:
  9. Michael Montague (mikemon) 17-Jul-1990
  10. Revision History:
  11. Mazhar Mohammed (mazharm) 11-08-1996 - Major re-haul to support async
  12. - Added support for Async RPC, Pipes
  13. - Changed class structure
  14. Kamen Moutafov (kamenm) Jan-2000 Support for multiple transfer syntaxes
  15. Kamen Moutafov (KamenM) Dec 99 - Feb 2000 - Support for cell debugging stuff
  16. --*/
  17. #ifndef __OSFCLNT_HXX__
  18. #define __OSFCLNT_HXX__
  19. enum OSF_CCALL_STATE
  20. {
  21. //
  22. // Need to open the connection and bind, in order to
  23. // handle the call
  24. //
  25. NeedOpenAndBind = 0,
  26. //
  27. // Need to send an alter context on the connection
  28. // in order to handle this call
  29. //
  30. NeedAlterContext,
  31. //
  32. // We sent an alter-context, we are waiting for a reply
  33. //
  34. WaitingForAlterContext,
  35. //
  36. // The call is still sending the non pipe data
  37. // we need to finish sending this before
  38. // we can move on the the next call.
  39. //
  40. SendingFirstBuffer,
  41. //
  42. // The call is now sending pipe data
  43. //
  44. SendingMoreData,
  45. //
  46. // The the call is done sending data. It is now waiting for a reply.
  47. // The reply may be either a response or a callback.
  48. //
  49. WaitingForReply,
  50. //
  51. // The call is receiving a callback from the server
  52. //
  53. InCallbackRequest,
  54. //
  55. // The call is in the process of sending a reply to a callback
  56. //
  57. InCallbackReply,
  58. //
  59. // We move into this state after receiving the first fragment
  60. //
  61. Receiving,
  62. //
  63. // Some failure occured. the call is now in an
  64. // aborted state
  65. //
  66. Aborted,
  67. //
  68. // The call is complete
  69. //
  70. Complete
  71. } ;
  72. //
  73. // Maximum retries in light of getting a shutdown
  74. // or closed in doing a bind or shutdown
  75. //
  76. #define MAX_RETRIES 3
  77. // 15 min timeout for bind
  78. #define RPC_C_SERVER_BIND_TIMEOUT 15*60*1000
  79. //
  80. // These values specify the minimum amount of time in milliseconds to wait before
  81. // deleting an idle connection. The second is the more aggressive. It will be used
  82. // when we have more than 500 connections in an association
  83. //
  84. const ULONG AGGRESSIVE_TIMEOUT_THRESHOLD = 500;
  85. const ULONG CLIENT_DISCONNECT_TIME1 = 10 * 1000;
  86. const ULONG CLIENT_DISCONNECT_TIME2 = 5 * 1000;
  87. #define InqTransCConnection(RpcTransportConnection) \
  88. ((OSF_CCONNECTION *) \
  89. ((char *) RpcTransportConnection - sizeof(OSF_CCONNECTION)))
  90. #define TransConnection() ((RPC_TRANSPORT_CONNECTION) \
  91. ((char *) this+sizeof(OSF_CCONNECTION)))
  92. #define TransResolverHint() ((void *) ((char *) this+sizeof(OSF_CASSOCIATION)))
  93. class OSF_CASSOCIATION;
  94. class OSF_CCONNECTION ;
  95. class OSF_BINDING ;
  96. class OSF_CCALL ;
  97. extern MUTEX *AssocDictMutex;
  98. class OSF_RECURSIVE_ENTRY
  99. /*++
  100. Class Description:
  101. This class is used to describe the entries in the dictionary of
  102. recursive calls maintained by each binding handle.
  103. Fields:
  104. Thread - Contains the thread owning this recursive call.
  105. RpcInterfaceInformation - Contains information describing the
  106. interface
  107. CCall - Contains the call
  108. --*/
  109. {
  110. friend class OSF_BINDING_HANDLE;
  111. private:
  112. THREAD_IDENTIFIER Thread;
  113. PRPC_CLIENT_INTERFACE RpcInterfaceInformation;
  114. OSF_CCALL * CCall;
  115. public:
  116. OSF_RECURSIVE_ENTRY (
  117. IN THREAD_IDENTIFIER Thread,
  118. IN PRPC_CLIENT_INTERFACE RpcInterfaceInformation,
  119. IN OSF_CCALL * CCall
  120. );
  121. OSF_CCALL *
  122. IsThisMyRecursiveCall (
  123. IN THREAD_IDENTIFIER Thread,
  124. IN PRPC_CLIENT_INTERFACE RpcInterfaceInformation
  125. );
  126. };
  127. inline
  128. OSF_RECURSIVE_ENTRY::OSF_RECURSIVE_ENTRY (
  129. IN THREAD_IDENTIFIER Thread,
  130. IN PRPC_CLIENT_INTERFACE RpcInterfaceInformation,
  131. IN OSF_CCALL * CCall
  132. )
  133. /*++
  134. Routine Description:
  135. All we do in this constructor is stash the arguments passed to us
  136. away in the object.
  137. Arguments:
  138. Thread - Supplies the thread for which this is the recursive call.
  139. RpcInterfaceInformation - Supplies information describing the
  140. interface
  141. CCall - Supplies the recursive call.
  142. --*/
  143. {
  144. this->Thread = Thread;
  145. this->RpcInterfaceInformation = RpcInterfaceInformation;
  146. this->CCall = CCall;
  147. }
  148. inline OSF_CCALL *
  149. OSF_RECURSIVE_ENTRY::IsThisMyRecursiveCall (
  150. IN THREAD_IDENTIFIER Thread,
  151. IN PRPC_CLIENT_INTERFACE RpcInterfaceInformation
  152. )
  153. /*++
  154. Routine Description:
  155. This routine determines if this object contains the recursive call
  156. for the specified thread and interface information.
  157. Arguments:
  158. Thread - Supplies the thread.
  159. RpcInterfaceInformation - Supplies the interface information.
  160. Return Value:
  161. If this object contains the recursive call corresponding to the
  162. specified thread and interface information, then the connection is
  163. returned. Otherwise, zero will be returned.
  164. --*/
  165. {
  166. return((((Thread == this->Thread)
  167. && (RpcInterfaceInformation == this->RpcInterfaceInformation))
  168. ? CCall : 0));
  169. }
  170. NEW_SDICT(OSF_RECURSIVE_ENTRY);
  171. class RPC_TOKEN
  172. {
  173. public:
  174. HANDLE hToken;
  175. LUID ModifiedId;
  176. int RefCount;
  177. int Key;
  178. RPC_TOKEN (HANDLE hToken, LUID *pModifiedId)
  179. {
  180. this->hToken = hToken;
  181. RefCount = 1;
  182. FastCopyLUIDAligned(&ModifiedId, pModifiedId);
  183. }
  184. ~RPC_TOKEN ()
  185. {
  186. CloseHandle(hToken);
  187. }
  188. };
  189. class OSF_BINDING_HANDLE : public BINDING_HANDLE
  190. /*++
  191. Class Description:
  192. Client applications use instances (referenced via an RPC_BINDING_HANDLE)
  193. of this class to make remote procedure calls.
  194. Fields:
  195. Association - Contains a pointer to the association used by this
  196. binding handle. The association can allocate connection for
  197. making remote procedure calls. Before the first remote procedure
  198. call is made using this binding handle, the Association will
  199. be zero. When the first remote procedure call is made, an
  200. assocation will be found or created for use by this binding handle.
  201. DceBinding - Before the first remote procedure call for this binding
  202. handle, this will contain the DCE binding information necessary
  203. to create or find an association to be used by this binding handle.
  204. After we have an association, this field will be zero.
  205. TransportInterface - This field is the same as DceBinding, except that
  206. it points to a rpc client info data structure used for describing
  207. a loadable transport.
  208. RecursiveCalls - This is a dictionary of recursive calls indexed
  209. by thread identifier and rpc interface information.
  210. BindingMutex - The binding handle can be used by more than one thread
  211. at a time. Hence, we need to serialize access to the object;
  212. we use this mutex for that.
  213. ReferenceCount - We count the number of active connections and the
  214. application RPC_BINDING_HANDLE which point at this object. This
  215. is so that we know when to free it.
  216. --*/
  217. {
  218. friend class OSF_CCALL;
  219. private:
  220. OSF_CASSOCIATION * Association;
  221. DCE_BINDING * DceBinding;
  222. TRANS_INFO *TransInfo ;
  223. OSF_RECURSIVE_ENTRY_DICT RecursiveCalls;
  224. UINT ReferenceCount;
  225. RPC_TOKEN *pToken;
  226. public:
  227. // set for Remote named pipes only
  228. BOOL fNamedPipe;
  229. BOOL TransAuthInitialized;
  230. BOOL fDynamicEndpoint;
  231. OSF_BINDING_HANDLE (
  232. IN OUT RPC_STATUS * RpcStatus
  233. );
  234. ~OSF_BINDING_HANDLE (
  235. );
  236. virtual RPC_STATUS
  237. NegotiateTransferSyntax (
  238. IN OUT PRPC_MESSAGE Message
  239. );
  240. virtual RPC_STATUS
  241. GetBuffer (
  242. IN OUT PRPC_MESSAGE Message,
  243. IN UUID *ObjectUuid
  244. );
  245. virtual RPC_STATUS
  246. BindingCopy (
  247. OUT BINDING_HANDLE * * DestinationBinding,
  248. IN UINT MaintainContext
  249. );
  250. virtual RPC_STATUS
  251. BindingFree (
  252. );
  253. virtual RPC_STATUS
  254. PrepareBindingHandle (
  255. IN TRANS_INFO * TransportInterface,
  256. IN DCE_BINDING * DceBinding
  257. );
  258. virtual RPC_STATUS
  259. ToStringBinding (
  260. OUT RPC_CHAR * * StringBinding
  261. );
  262. virtual RPC_STATUS
  263. ResolveBinding (
  264. IN RPC_CLIENT_INTERFACE * RpcClientInterface
  265. );
  266. virtual RPC_STATUS
  267. BindingReset (
  268. );
  269. virtual RPC_STATUS
  270. InquireTransportType(
  271. OUT UINT *Type
  272. )
  273. { *Type = TRANSPORT_TYPE_CN; return(RPC_S_OK); }
  274. virtual ULONG
  275. MapAuthenticationLevel (
  276. IN ULONG AuthenticationLevel
  277. );
  278. virtual void
  279. AddReference (
  280. )
  281. {
  282. BindingMutex.Request();
  283. ReferenceCount++;
  284. BindingMutex.Clear();
  285. }
  286. RPC_STATUS
  287. AllocateCCall (
  288. OUT OSF_CCALL * * CCall,
  289. IN PRPC_MESSAGE Message,
  290. OUT BOOL *Retry
  291. );
  292. RPC_STATUS
  293. AddRecursiveEntry (
  294. IN OSF_CCALL * CCall,
  295. IN PRPC_CLIENT_INTERFACE RpcInterfaceInformation
  296. );
  297. void
  298. RemoveRecursiveCall (
  299. IN OSF_CCALL * CCall
  300. );
  301. OSF_CASSOCIATION *
  302. TheAssociation (
  303. ) {return(Association);}
  304. OSF_CASSOCIATION *
  305. FindOrCreateAssociation (
  306. IN DCE_BINDING * DceBinding,
  307. IN TRANS_INFO * TransInfo,
  308. IN RPC_CLIENT_INTERFACE *InterfaceInfo
  309. );
  310. RPC_STATUS
  311. AcquireCredentialsForTransport (
  312. );
  313. BOOL
  314. SwapToken (
  315. HANDLE *OldToken
  316. );
  317. void Unbind ();
  318. virtual RPC_STATUS
  319. SetTransportOption( unsigned long option,
  320. ULONG_PTR optionValue );
  321. virtual RPC_STATUS
  322. InqTransportOption( unsigned long option,
  323. ULONG_PTR * pOptionValue );
  324. };
  325. const unsigned int BindingListPresent = 1;
  326. class OSF_CCONNECTION ;
  327. enum CANCEL_STATE {
  328. CANCEL_NOTREGISTERED = 0,
  329. CANCEL_INFINITE,
  330. CANCEL_NOTINFINITE
  331. };
  332. class OSF_CCALL : public CCALL
  333. /*++
  334. Class Description:
  335. This class encapsulates an RPC call.
  336. Fields:
  337. PresentationContext - This field is only valid when there is a remote
  338. procedure call in progress on this connection; it contains the
  339. presentation context for the call.
  340. DispatchTableCallback - This field is only valid when there is a remote
  341. procedure call in progress on this connection; it contains the
  342. dispatch table to use for callbacks.
  343. Association - Contains a pointer to the association which owns this
  344. connection.
  345. TokenLength - Contains the maximum size of a token for the security
  346. package being used by this connection; we need to keep track of
  347. this for the third leg authentication case.
  348. --*/
  349. {
  350. //
  351. // This class will only access the AssociationKey member.
  352. //
  353. friend class OSF_CASSOCIATION;
  354. friend class OSF_CCONNECTION;
  355. friend class OSF_BINDING_HANDLE;
  356. public:
  357. OSF_CCALL_STATE CurrentState ;
  358. private:
  359. OSF_CCONNECTION *Connection ;
  360. OSF_BINDING_HANDLE *BindingHandle;
  361. #ifdef DEBUGRPC
  362. int CallbackLevel;
  363. #endif
  364. // don't access the struct members directly - only through
  365. // the access functions - this will ensure that the
  366. // contents of the struct is properly checked. Async first
  367. // calls on new connection have both elements valid if there
  368. // are no preferences. Since this is the only case where
  369. // this condition is true, we can use it as a flag.
  370. struct
  371. {
  372. // NULL if no binding is selected
  373. OSF_BINDING *SelectedBinding;
  374. // this is the list of differning only by transfer syntax
  375. // bindings this call can use. It can have one or more
  376. // elements.
  377. // This may be NULL if the call doesn't need a list
  378. OSF_BINDING *AvailableBindingsList;
  379. } Bindings;
  380. void *CurrentBuffer ;
  381. BOOL fDataLengthNegotiated;
  382. int CurrentOffset ;
  383. ULONG CurrentBufferLength ;
  384. ULONG CallId;
  385. UINT RcvBufferLength ;
  386. BOOL FirstSend ;
  387. PRPC_DISPATCH_TABLE DispatchTableCallback;
  388. UINT MaximumFragmentLength;
  389. // starts from 0, and set to non-zero if security is used after
  390. // negotiating the bind
  391. UINT MaxSecuritySize ;
  392. UINT MaxDataLength;
  393. int ProcNum ;
  394. unsigned char *ReservedForSecurity ;
  395. UINT SecBufferLength;
  396. // When the call is created, set to 0, because we don't know whether
  397. // there is object UUID or not. During GetBuffer we will know, and then
  398. // we will set it properly. Starting from 0 allows the bind and GetBuffer
  399. // threads (if different) to check and to synchronize the updating of the
  400. // max fragment size, since it depends both on the object UUID and
  401. // the security negotiation
  402. UINT HeaderSize;
  403. UINT AdditionalSpaceForSecurity;
  404. ULONG SavedHeaderSize;
  405. void * SavedHeader;
  406. void * LastBuffer ;
  407. EVENT SyncEvent ;
  408. UINT ActualBufferLength;
  409. UINT NeededLength;
  410. void *CallSendContext;
  411. INTERLOCKED_INTEGER fAdvanceCallCount;
  412. BOOL fPeerChoked;
  413. // Extended Error Info stuff
  414. // used in async calls only to hold
  415. // information b/n call failure and
  416. // RpcAsyncCompleteCall
  417. ExtendedErrorInfo *EEInfo;
  418. BOOL fDoFlowControl;
  419. public:
  420. BOOL fLastSendComplete;
  421. MUTEX CallMutex ;
  422. int RecursiveCallsKey;
  423. //
  424. // Indicates the call stack. Whenever a request message is sent or
  425. // received, the stack is incremented. Likewise, whenever a response
  426. // message is sent or received, the stack is decremented.
  427. //
  428. int CallStack;
  429. BOOL fCallCancelled;
  430. CANCEL_STATE CancelState;
  431. private:
  432. QUEUE BufferQueue ;
  433. BOOL InReply;
  434. BOOL fChoked;
  435. OSF_CCALL (
  436. RPC_STATUS * pStatus
  437. );
  438. public:
  439. virtual~OSF_CCALL (
  440. );
  441. virtual RPC_STATUS
  442. NegotiateTransferSyntax (
  443. IN OUT PRPC_MESSAGE Message
  444. );
  445. virtual RPC_STATUS
  446. GetBuffer (
  447. IN OUT PRPC_MESSAGE Message,
  448. IN UUID *ObjectUuid = 0
  449. );
  450. RPC_STATUS
  451. GetBufferWithoutCleanup (
  452. IN OUT PRPC_MESSAGE Message,
  453. IN UUID *ObjectUuid
  454. );
  455. virtual RPC_STATUS
  456. SendReceive (
  457. IN OUT PRPC_MESSAGE Message
  458. );
  459. RPC_STATUS
  460. SendReceiveHelper (
  461. IN OUT PRPC_MESSAGE Message,
  462. OUT BOOL *fRetry
  463. );
  464. virtual RPC_STATUS
  465. Send (
  466. IN PRPC_MESSAGE Message
  467. );
  468. virtual RPC_STATUS
  469. Receive (
  470. IN PRPC_MESSAGE Message,
  471. IN UINT Size
  472. );
  473. virtual void
  474. FreeBuffer (
  475. IN PRPC_MESSAGE Message
  476. );
  477. virtual void
  478. FreePipeBuffer (
  479. IN PRPC_MESSAGE Message
  480. );
  481. virtual RPC_STATUS
  482. ReallocPipeBuffer (
  483. IN PRPC_MESSAGE Message,
  484. IN UINT NewSize
  485. );
  486. virtual RPC_STATUS
  487. AsyncSend (
  488. IN OUT PRPC_MESSAGE Message
  489. );
  490. virtual RPC_STATUS
  491. AsyncReceive (
  492. IN OUT PRPC_MESSAGE Message,
  493. IN UINT Size
  494. );
  495. virtual void
  496. ProcessSendComplete (
  497. IN RPC_STATUS EventStatus,
  498. IN BUFFER Buffer
  499. );
  500. virtual RPC_STATUS
  501. CancelAsyncCall (
  502. IN BOOL fAbort
  503. );
  504. virtual void
  505. FreeObject (
  506. );
  507. RPC_STATUS
  508. SendHelper (
  509. IN PRPC_MESSAGE Message,
  510. OUT BOOL *fFirstSend
  511. );
  512. RPC_STATUS
  513. SendData (
  514. IN BUFFER Buffer
  515. );
  516. RPC_STATUS
  517. SendMoreData (
  518. IN BUFFER Buffer
  519. );
  520. RPC_STATUS
  521. ActuallyAllocateBuffer (
  522. OUT void * * Buffer,
  523. IN UINT BufferLength
  524. );
  525. void
  526. ActuallyFreeBuffer (
  527. IN void * Buffer
  528. );
  529. //
  530. // Actually perform the buffer allocation.
  531. //
  532. RPC_STATUS
  533. GetBufferDo (
  534. IN UINT culRequiredLength,
  535. OUT void * * ppBuffer,
  536. IN int fDataValid = 0,
  537. IN int DataLength = 0
  538. );
  539. void
  540. FreeBufferDo (
  541. IN void *Buffer
  542. );
  543. RPC_STATUS
  544. ActivateCall (
  545. IN OSF_BINDING_HANDLE *BindingHandle,
  546. IN OSF_BINDING *Binding,
  547. IN OSF_BINDING *AvailableBindingsList,
  548. IN ULONG CallIdToUse,
  549. IN OSF_CCALL_STATE InitialCallState,
  550. IN PRPC_DISPATCH_TABLE DispatchTable,
  551. IN OSF_CCONNECTION *CConnection
  552. );
  553. void
  554. FreeCCall (
  555. IN RPC_STATUS Status
  556. );
  557. RPC_STATUS
  558. SendCancelPDU(
  559. );
  560. RPC_STATUS
  561. SendOrphanPDU (
  562. );
  563. RPC_STATUS
  564. BindToServer (
  565. BOOL fAsyncBind
  566. );
  567. RPC_STATUS
  568. Cancel(
  569. void * ThreadHandle
  570. );
  571. RPC_STATUS
  572. InqWireIdForSnego (
  573. OUT unsigned char *WireId
  574. );
  575. RPC_STATUS
  576. BindingHandleToAsyncHandle (
  577. OUT void **AsyncHandle
  578. );
  579. // if fMultipleBindingsAvailable is set, the return value is a head of a linked
  580. // list. If fMultipleBindingsAvailable is FALSE, only the element in the return
  581. // value is meaningful
  582. inline OSF_BINDING *
  583. GetListOfAvaialbleBindings (
  584. OUT BOOL *fMultipleBindingsAvailable
  585. )
  586. {
  587. if (Bindings.AvailableBindingsList)
  588. {
  589. *fMultipleBindingsAvailable = TRUE;
  590. return Bindings.AvailableBindingsList;
  591. }
  592. else
  593. {
  594. *fMultipleBindingsAvailable = FALSE;
  595. return Bindings.SelectedBinding;
  596. }
  597. }
  598. RPC_STATUS
  599. BindCompleteNotify (
  600. IN p_result_t *OsfResult,
  601. IN int IndexOfPresentationContextAccepted,
  602. OUT OSF_BINDING **BindingNegotiated
  603. );
  604. #ifdef DEBUGRPC
  605. inline void EnterCallback(void)
  606. {
  607. CallbackLevel ++;
  608. }
  609. inline void ExitCallback(void)
  610. {
  611. CallbackLevel --;
  612. }
  613. inline BOOL IsCallInCallback(void)
  614. {
  615. return CallbackLevel > 0;
  616. }
  617. #endif
  618. private:
  619. void
  620. SendFault (
  621. IN RPC_STATUS Status,
  622. IN int DidNotExecute
  623. );
  624. #define MAX_ALLOC_Hint 16*1024
  625. RPC_STATUS
  626. EatAuthInfoFromPacket (
  627. IN rpcconn_request * Request,
  628. IN OUT UINT * RequestLength
  629. );
  630. BOOL
  631. ProcessReceivedPDU (
  632. IN void *Buffer,
  633. IN int BufferLength
  634. );
  635. RPC_STATUS
  636. GetCoalescedBuffer (
  637. IN PRPC_MESSAGE Message,
  638. IN BOOL BufferValid
  639. );
  640. RPC_STATUS
  641. SendAlterContextPDU (
  642. );
  643. RPC_STATUS
  644. GetCoalescedBuffer(
  645. IN PRPC_MESSAGE Message);
  646. RPC_STATUS
  647. FastSendReceive (
  648. IN OUT PRPC_MESSAGE Message,
  649. OUT BOOL *fRetry
  650. );
  651. RPC_STATUS
  652. SendNextFragment (
  653. IN unsigned char PacketType = rpc_request,
  654. IN BOOL fFirstSend = TRUE,
  655. OUT void **ReceiveBuffer = 0,
  656. OUT UINT *ReceivedLength = 0
  657. );
  658. RPC_STATUS
  659. ActuallyProcessPDU (
  660. IN rpcconn_common *Packet,
  661. IN UINT PacketLength,
  662. IN OUT PRPC_MESSAGE Message,
  663. IN BOOL fAsync = 0,
  664. OUT BOOL *pfSubmitReceive = NULL
  665. );
  666. RPC_STATUS
  667. ProcessResponse (
  668. IN rpcconn_response *Packet,
  669. IN PRPC_MESSAGE Message,
  670. OUT BOOL *pfSubmitReceive
  671. );
  672. RPC_STATUS
  673. ProcessRequestOrResponse (
  674. IN rpcconn_request *Request,
  675. IN UINT PacketLength,
  676. IN BOOL fRequest,
  677. IN PRPC_MESSAGE Message
  678. );
  679. RPC_STATUS
  680. DealWithCallback (
  681. IN rpcconn_request *Request,
  682. IN PRPC_MESSAGE Message
  683. );
  684. RPC_STATUS
  685. ReceiveReply (
  686. IN rpcconn_request *Request,
  687. IN PRPC_MESSAGE Message
  688. );
  689. void
  690. CallFailed (
  691. IN RPC_STATUS Status
  692. ) ;
  693. int
  694. QueueBuffer (
  695. IN void *Buffer,
  696. IN int BufferLength);
  697. BOOL
  698. IssueNotification (
  699. IN RPC_ASYNC_EVENT Event = RpcCallComplete
  700. );
  701. RPC_STATUS ReserveSpaceForSecurityIfNecessary (void);
  702. void UpdateObjectUUIDInfo (IN UUID *ObjectUuid);
  703. void UpdateMaxFragLength (const IN ULONG AuthnLevel);
  704. RPC_STATUS AutoRetryCall(IN OUT RPC_MESSAGE *Message, IN BOOL fSendReceivePath,
  705. IN OSF_BINDING_HANDLE *LocalBindingHandle, IN RPC_STATUS CurrentStatus,
  706. IN RPC_ASYNC_STATE *AsyncState OPTIONAL);
  707. void CleanupOldCallOnAutoRetry(IN PVOID Buffer, IN BOOL fSendReceivePath,
  708. IN RPC_STATUS CurrentStatus)
  709. {
  710. FreeBufferDo(Buffer);
  711. if (fSendReceivePath)
  712. FreeCCall(CurrentStatus);
  713. else
  714. {
  715. //
  716. // Remove the call reference, CCALL--
  717. //
  718. RemoveReference();
  719. }
  720. }
  721. OSF_BINDING *GetSelectedBinding(void)
  722. {
  723. ASSERT(Bindings.SelectedBinding != NULL);
  724. return Bindings.SelectedBinding;
  725. }
  726. OSF_BINDING *GetBindingList(void)
  727. {
  728. ASSERT(Bindings.AvailableBindingsList != NULL);
  729. return Bindings.AvailableBindingsList;
  730. }
  731. void *
  732. ActualBuffer (
  733. IN void *Buffer
  734. );
  735. RPC_STATUS
  736. CallCancelled (
  737. OUT PDWORD Timeout
  738. );
  739. RPC_STATUS
  740. RegisterCallForCancels (
  741. );
  742. void
  743. UnregisterCallForCancels (
  744. );
  745. void * operator new (
  746. size_t allocBlock,
  747. unsigned int xtraBytes
  748. );
  749. RPC_STATUS
  750. UpdateBufferSize (
  751. IN OUT void **Buffer,
  752. IN int CurrentBufferLength
  753. );
  754. inline BOOL
  755. fOkToAdvanceCall()
  756. {
  757. return (fAdvanceCallCount.Increment() == 2);
  758. }
  759. virtual RPC_STATUS
  760. InqSecurityContext (
  761. OUT void **SecurityContextHandle
  762. );
  763. static RPC_STATUS
  764. NegotiateTransferSyntaxAndGetBuffer (
  765. IN OUT PRPC_MESSAGE Message,
  766. IN UUID *ObjectUuid
  767. );
  768. inline ULONG
  769. GetBindingHandleTimeout (
  770. IN OSF_BINDING_HANDLE *BindingToUse
  771. )
  772. {
  773. RPC_STATUS RpcStatus;
  774. ULONG_PTR OptionValue;
  775. RpcStatus = BindingToUse->OSF_BINDING_HANDLE::InqTransportOption(
  776. RPC_C_OPT_CALL_TIMEOUT,
  777. &OptionValue);
  778. ASSERT(RpcStatus == RPC_S_OK);
  779. if (OptionValue == 0)
  780. return INFINITE;
  781. else
  782. return (ULONG) OptionValue;
  783. }
  784. inline RPC_STATUS
  785. GetStatusForTimeout (
  786. IN OSF_BINDING_HANDLE *BindingHandleToUse,
  787. IN RPC_STATUS Status,
  788. BOOL fBindingHandleTimeoutUsed
  789. )
  790. {
  791. if (Status == RPC_P_TIMEOUT)
  792. {
  793. if (fBindingHandleTimeoutUsed)
  794. {
  795. Status = RPC_S_CALL_CANCELLED;
  796. RpcpErrorAddRecord(EEInfoGCRuntime,
  797. Status,
  798. EEInfoDLGetStatusForTimeout10,
  799. RPC_P_TIMEOUT,
  800. GetBindingHandleTimeout(BindingHandle));
  801. }
  802. else
  803. {
  804. Status = RPC_S_CALL_FAILED_DNE;
  805. RpcpErrorAddRecord(EEInfoGCRuntime,
  806. Status,
  807. EEInfoDLGetStatusForTimeout20,
  808. (ULONG)RPC_P_TIMEOUT,
  809. (ULONG)RPC_C_SERVER_BIND_TIMEOUT);
  810. }
  811. }
  812. return Status;
  813. }
  814. inline ULONG
  815. GetEffectiveTimeoutForBind (
  816. IN OSF_BINDING_HANDLE *BindingToUse,
  817. OUT BOOL *fBindingHandleTimeoutUsed
  818. )
  819. {
  820. ULONG Timeout;
  821. Timeout = GetBindingHandleTimeout(BindingToUse);
  822. if (Timeout > RPC_C_SERVER_BIND_TIMEOUT)
  823. {
  824. Timeout = RPC_C_SERVER_BIND_TIMEOUT;
  825. *fBindingHandleTimeoutUsed = FALSE;
  826. }
  827. else
  828. {
  829. *fBindingHandleTimeoutUsed = TRUE;
  830. }
  831. return Timeout;
  832. }
  833. };
  834. inline void *
  835. OSF_CCALL::operator new (
  836. size_t allocBlock,
  837. unsigned int xtraBytes
  838. )
  839. {
  840. I_RPC_HANDLE pvTemp = (I_RPC_HANDLE) new char[allocBlock + xtraBytes];
  841. return(pvTemp);
  842. }
  843. inline void
  844. OSF_CCALL::FreeObject (
  845. )
  846. {
  847. if (AsyncStatus == RPC_S_ASYNC_CALL_PENDING)
  848. {
  849. AsyncStatus = RPC_S_CALL_FAILED;
  850. }
  851. FreeCCall(AsyncStatus);
  852. }
  853. inline RPC_STATUS
  854. OSF_CCALL::RegisterCallForCancels (
  855. )
  856. {
  857. RPC_STATUS Status;
  858. if (pAsync == 0)
  859. {
  860. Status = RegisterForCancels(this);
  861. if (Status != RPC_S_OK)
  862. {
  863. return Status;
  864. }
  865. if (ThreadGetRpcCancelTimeout() == RPC_C_CANCEL_INFINITE_TIMEOUT)
  866. {
  867. CancelState = CANCEL_INFINITE;
  868. }
  869. else
  870. {
  871. CancelState = CANCEL_NOTINFINITE;
  872. }
  873. }
  874. return RPC_S_OK;
  875. }
  876. inline void
  877. OSF_CCALL::UnregisterCallForCancels (
  878. )
  879. {
  880. if (pAsync == 0)
  881. {
  882. EVAL_AND_ASSERT(RPC_S_OK == UnregisterForCancels());
  883. }
  884. }
  885. inline void *
  886. OSF_CCALL::ActualBuffer (
  887. IN void *Buffer
  888. )
  889. {
  890. ASSERT (HeaderSize != 0);
  891. if (UuidSpecified)
  892. {
  893. Buffer = (char *) Buffer - sizeof(rpcconn_request) - sizeof(UUID);
  894. }
  895. else
  896. {
  897. Buffer = (char *) Buffer - sizeof(rpcconn_request);
  898. }
  899. return Buffer;
  900. }
  901. inline int
  902. OSF_CCALL::QueueBuffer (
  903. IN void *Buffer,
  904. IN int BufferLength
  905. )
  906. {
  907. RcvBufferLength += BufferLength;
  908. return BufferQueue.PutOnQueue(Buffer, BufferLength);
  909. }
  910. NEW_SDICT2(OSF_CCALL, PVOID);
  911. #define SYNC_CONN_FREE 0
  912. #define SYNC_CONN_BUSY -1
  913. #define ASYNC_CONN_BUSY -2
  914. #define ASYNC_CONN_FREE -3
  915. enum CONNECTION_STATES
  916. {
  917. ConnUninitialized,
  918. ConnAborted,
  919. ConnOpen
  920. };
  921. const unsigned int FreshFromCache = 1;
  922. enum FAILURE_COUNT_STATE
  923. {
  924. FailureCountUnknown,
  925. FailureCountNotExceeded,
  926. FailureCountExceeded
  927. };
  928. class OSF_CCONNECTION : public REFERENCED_OBJECT
  929. /*++
  930. Class Description:
  931. This class encapsulates a transport connection. The transport
  932. connection may be used by one or more RPC calls. Each RPC
  933. call is encapsulated by an CALL object. This object may
  934. be exclusively used by a call. Each connection is owned by
  935. exacly one thread (ie: all calls on a connection have been
  936. initiated by a single thread).
  937. Fields:
  938. Association: Pointer to the association object
  939. ConnectionKey: Key to our entry in the dictionary of connections in
  940. the association.
  941. ThreadId: Thread Id of the thread owning this call.
  942. DceSecurityInfo - Contains information necessary for DCE security to
  943. work properly. This includes the association uuid (a different
  944. value for each connection), and sequence numbers (both directions).
  945. ThirdLegAuthNeeded - Contains a flag indicating whether or not third
  946. leg authentication is needed; a non-zero value indicates that it
  947. is needed.
  948. ClientSecurityContext - Optionally contains the security context being
  949. used for this connection.
  950. AdditionalSpaceForSecurity - Contains the amount of space to save
  951. for security in each buffer we allocate.
  952. LastTimeUsed - Contains the time in seconds when this connection was
  953. last used.
  954. CurrentCall - The call on which we are currently **sending** data
  955. ClientInfo - Contains the pointers to the loadable transport routines
  956. for the transport type of this connection.
  957. fConnectionAborted - If this field is non-zero it indicates that the
  958. connection has been aborted, meaning that any attempts to send
  959. or receive data on the connection will fail.
  960. --*/
  961. {
  962. friend class OSF_CASSOCIATION;
  963. friend class OSF_CCALL;
  964. friend class OSF_BINDING_HANDLE;
  965. private:
  966. OSF_CASSOCIATION * Association;
  967. OSF_CCALL *CurrentCall ;
  968. int ConnectionKey;
  969. CONNECTION_STATES State;
  970. unsigned char WireAuthId;
  971. unsigned short MaxFrag;
  972. ULONG ThreadId ;
  973. BOOL CachedCCallAvailable ;
  974. ULONG MaxSavedHeaderSize;
  975. OSF_CCALL *CachedCCall ;
  976. ULONG SavedHeaderSize;
  977. unsigned int ComTimeout ;
  978. void * SavedHeader;
  979. BOOL AdditionalLegNeeded;
  980. ULONG LastTimeUsed;
  981. UINT TokenLength;
  982. UINT AdditionalSpaceForSecurity;
  983. BOOL fIdle ;
  984. BOOL fExclusive ;
  985. BOOL fConnectionAborted;
  986. CompositeFlags Flags;
  987. BITSET Bindings;
  988. QUEUE CallQueue ;
  989. MUTEX ConnMutex ;
  990. OSF_CCALL_DICT2 ActiveCalls ;
  991. SECURITY_CONTEXT ClientSecurityContext;
  992. RPC_CONNECTION_TRANSPORT * ClientInfo;
  993. union
  994. {
  995. void *ConnSendContext ;
  996. OSF_CCONNECTION *NextConnection; // used to link connections in some case
  997. } u;
  998. DCE_SECURITY_INFO DceSecurityInfo;
  999. void *BufferToFree;
  1000. BOOL ConnectionReady;
  1001. BOOL fSeparateConnection;
  1002. public:
  1003. OSF_CCONNECTION (
  1004. IN OSF_CASSOCIATION *Association,
  1005. IN RPC_CONNECTION_TRANSPORT * RpcClientInfo,
  1006. IN unsigned int Timeout,
  1007. IN CLIENT_AUTH_INFO * myAuthInfo,
  1008. IN BOOL fExclusive,
  1009. IN BOOL fSeparateConnection,
  1010. OUT RPC_STATUS * pStatus
  1011. );
  1012. virtual ~OSF_CCONNECTION (
  1013. );
  1014. virtual void
  1015. ProcessSendComplete (
  1016. IN RPC_STATUS EventStatus,
  1017. IN BUFFER Buffer
  1018. );
  1019. RPC_STATUS
  1020. TransInitialize (
  1021. IN RPC_CHAR *NetworkAddress,
  1022. IN RPC_CHAR *NetworkOptions
  1023. )
  1024. {
  1025. if (ClientInfo->Initialize)
  1026. {
  1027. return ClientInfo->Initialize(TransConnection(),
  1028. NetworkAddress,
  1029. NetworkOptions,
  1030. (fExclusive == 0));
  1031. }
  1032. return (RPC_S_OK);
  1033. }
  1034. void
  1035. TransInitComplete (
  1036. )
  1037. {
  1038. if (ClientInfo->InitComplete)
  1039. {
  1040. ClientInfo->InitComplete(TransConnection());
  1041. }
  1042. }
  1043. RPC_STATUS
  1044. TransOpen (
  1045. IN OSF_BINDING_HANDLE * BindingHandle,
  1046. IN RPC_CHAR * RpcProtocolSequence,
  1047. IN RPC_CHAR * NetworkAddress,
  1048. IN RPC_CHAR * Endpoint,
  1049. IN RPC_CHAR * NetworkOptions,
  1050. IN void *ResolverHint,
  1051. IN BOOL fHintInitialized,
  1052. IN ULONG Timeout
  1053. ) ;
  1054. RPC_STATUS
  1055. TransReceive (
  1056. OUT void * * Buffer,
  1057. OUT unsigned int * BufferLength,
  1058. IN ULONG Timeout
  1059. );
  1060. RPC_STATUS
  1061. TransSend (
  1062. IN void * Buffer,
  1063. IN unsigned int BufferLength,
  1064. IN BOOL fDisableShutdownCheck,
  1065. IN BOOL fDisableCancelCheck,
  1066. IN ULONG Timeout
  1067. );
  1068. #ifdef WIN96
  1069. RPC_STATUS
  1070. TransClose (
  1071. );
  1072. #endif
  1073. RPC_STATUS
  1074. TransSendReceive (
  1075. IN void * SendBuffer,
  1076. IN unsigned int SendBufferLength,
  1077. OUT void * * ReceiveBuffer,
  1078. OUT unsigned int * ReceiveBufferLength,
  1079. IN ULONG Timeout
  1080. );
  1081. RPC_STATUS
  1082. TransAsyncSend (
  1083. IN void * SendBuffer,
  1084. IN unsigned int SendBufferLength,
  1085. IN void *SendContext
  1086. ) ;
  1087. RPC_STATUS
  1088. TransAsyncReceive (
  1089. ) ;
  1090. RPC_STATUS
  1091. TransPostEvent (
  1092. IN PVOID Context
  1093. ) ;
  1094. void
  1095. TransAbortConnection (
  1096. );
  1097. void
  1098. TransClose (
  1099. );
  1100. unsigned int
  1101. TransMaximumSend (
  1102. );
  1103. unsigned int
  1104. GuessPacketLength (
  1105. );
  1106. void * operator new (
  1107. size_t allocBlock,
  1108. unsigned int xtraBytes
  1109. );
  1110. RPC_STATUS
  1111. TransGetBuffer (
  1112. OUT void * * Buffer,
  1113. IN UINT BufferLength
  1114. );
  1115. void
  1116. TransFreeBuffer (
  1117. IN void * Buffer
  1118. );
  1119. RPC_STATUS
  1120. TransReallocBuffer (
  1121. IN OUT void * * Buffer,
  1122. IN UINT OldSize,
  1123. IN UINT NewSize
  1124. );
  1125. RPC_STATUS
  1126. AllocateCCall (
  1127. OUT OSF_CCALL **CCall
  1128. );
  1129. RPC_STATUS
  1130. AddCall (
  1131. IN OSF_CCALL *CCall
  1132. );
  1133. void
  1134. FreeCCall (
  1135. IN OSF_CCALL *CCall,
  1136. IN RPC_STATUS Status,
  1137. IN ULONG ComTimeout
  1138. );
  1139. RPC_STATUS
  1140. OpenConnectionAndBind (
  1141. IN OSF_BINDING_HANDLE *BindingHandle,
  1142. IN ULONG Timeout,
  1143. IN BOOL fAlwaysNegotiateNDR20,
  1144. OUT FAILURE_COUNT_STATE *fFailureCountExceeded OPTIONAL
  1145. );
  1146. RPC_STATUS
  1147. ActuallyDoBinding (
  1148. IN OSF_CCALL *CCall,
  1149. IN ULONG MyAssocGroupId,
  1150. IN BOOL fNewConnection,
  1151. IN ULONG Timeout,
  1152. OUT OSF_BINDING **BindingNegotiated,
  1153. OUT BOOL *fPossibleAssociationReset,
  1154. OUT FAILURE_COUNT_STATE *fFailureCountExceeded OPTIONAL
  1155. );
  1156. RPC_STATUS
  1157. SendBindPacket (
  1158. IN BOOL fInitialPass,
  1159. IN OSF_CCALL *Call,
  1160. IN ULONG AssocGroup,
  1161. IN unsigned char PacketType,
  1162. IN ULONG Timeout,
  1163. IN BOOL fAsync = 1,
  1164. OUT rpcconn_common * * Buffer = 0,
  1165. OUT UINT * BufferLength = 0,
  1166. IN rpcconn_common * InputPacket = 0,
  1167. IN unsigned int InputPacketLength = 0
  1168. );
  1169. RPC_STATUS
  1170. MaybeDo3rdLegAuth (
  1171. IN void * Buffer,
  1172. IN UINT BufferLength
  1173. );
  1174. //
  1175. // Set the value of the max frag for the connection.
  1176. //
  1177. void
  1178. SetMaxFrag (
  1179. IN unsigned short max_xmit_frag,
  1180. IN unsigned short max_recv_frag
  1181. );
  1182. UINT
  1183. InqMaximumFragmentLength (
  1184. );
  1185. int
  1186. AddPContext (
  1187. IN int PresentContext
  1188. ) {return(Bindings.Insert(PresentContext));}
  1189. void
  1190. DeletePContext (
  1191. IN int PresentContext
  1192. ) {Bindings.Delete(PresentContext);}
  1193. int
  1194. SupportedPContext (
  1195. IN int *PresentationContexts,
  1196. IN int NumberOfPresentationContexts,
  1197. OUT int *PresentationContextSupported
  1198. );
  1199. int
  1200. SupportedAuthInfo (
  1201. IN CLIENT_AUTH_INFO * ClientAuthInfo,
  1202. IN BOOL fNamedPipe
  1203. );
  1204. RPC_STATUS
  1205. SendFragment (
  1206. IN rpcconn_common *pFragment,
  1207. IN OSF_CCALL *CCall,
  1208. IN UINT LastFragmentFlag,
  1209. IN UINT HeaderSize,
  1210. IN UINT MaxSecuritySize,
  1211. IN UINT DataLength,
  1212. IN UINT MaximumFragmentLength,
  1213. IN unsigned char *ReservedForSecurity,
  1214. IN BOOL fAsync,
  1215. IN void *SendContext,
  1216. IN ULONG Timeout,
  1217. OUT void **ReceiveBuffer,
  1218. OUT UINT *ReceiveBufferLength
  1219. );
  1220. void
  1221. ProcessReceiveComplete (
  1222. IN RPC_STATUS EventStatus,
  1223. IN BUFFER Buffer,
  1224. IN UINT BufferLength
  1225. );
  1226. ULONG
  1227. InquireSendSequenceNumber (
  1228. );
  1229. ULONG
  1230. InquireReceiveSequenceNumber (
  1231. );
  1232. RPC_CHAR *InqEndpoint(void);
  1233. RPC_CHAR *InqNetworkAddress(void);
  1234. void
  1235. IncSendSequenceNumber (
  1236. );
  1237. inline void
  1238. IncReceiveSequenceNumber (
  1239. );
  1240. void
  1241. NotifyCallDeleted (
  1242. );
  1243. void
  1244. SetLastTimeUsedToNow (
  1245. );
  1246. ULONG
  1247. InquireLastTimeUsed (
  1248. );
  1249. ULONG
  1250. GetAssocGroupId (
  1251. );
  1252. void
  1253. ConnectionAborted (
  1254. IN RPC_STATUS Status,
  1255. IN BOOL fShutdownAssoc = 1
  1256. );
  1257. void
  1258. AdvanceToNextCall (
  1259. );
  1260. RPC_STATUS
  1261. AddActiveCall (
  1262. IN ULONG CallId,
  1263. IN OSF_CCALL *CCall
  1264. );
  1265. RPC_STATUS
  1266. DealWithAlterContextResp (
  1267. IN OSF_CCALL *CCall,
  1268. IN rpcconn_common *Packet,
  1269. IN int PacketLength,
  1270. IN OUT BOOL *AlterContextToNDR20IfNDR64Negotiated
  1271. );
  1272. void
  1273. MakeConnectionIdle (
  1274. );
  1275. void
  1276. MakeConnectionActive (
  1277. );
  1278. BOOL
  1279. IsIdle (
  1280. );
  1281. void
  1282. DeleteConnection (
  1283. );
  1284. BOOL IsExclusive (void)
  1285. {
  1286. return fExclusive;
  1287. }
  1288. RPC_STATUS
  1289. ValidateHeader(
  1290. rpcconn_common * Buffer,
  1291. unsigned long BufferLength
  1292. );
  1293. RPC_STATUS
  1294. FinishSecurityContextSetup (
  1295. IN OSF_CCALL *Call,
  1296. IN unsigned long AssocGroup,
  1297. OUT rpcconn_common * * Buffer,
  1298. OUT unsigned int * BufferLength,
  1299. IN ULONG Timeout
  1300. );
  1301. RPC_STATUS
  1302. CallCancelled (
  1303. OUT PDWORD Timeout
  1304. );
  1305. void
  1306. WaitForSend(
  1307. );
  1308. BOOL
  1309. MatchModifiedId (
  1310. LUID *pModifiedId
  1311. )
  1312. {
  1313. if (ClientSecurityContext.DefaultLogonId)
  1314. {
  1315. return FALSE;
  1316. }
  1317. return (FastCompareLUIDAligned(pModifiedId, &ClientSecurityContext.ModifiedId));
  1318. }
  1319. void
  1320. MaybeAdvanceToNextCall(
  1321. OSF_CCALL *Call
  1322. )
  1323. {
  1324. if (fExclusive == 0
  1325. && CurrentCall == Call)
  1326. {
  1327. AdvanceToNextCall();
  1328. }
  1329. }
  1330. RPC_STATUS
  1331. AbortAndWait (
  1332. OSF_CCALL *Call
  1333. )
  1334. {
  1335. int retval;
  1336. // CCONN++
  1337. AddReference();
  1338. //
  1339. // There is still a race condition here
  1340. //
  1341. ConnMutex.Request();
  1342. ActiveCalls.Delete(IntToPtr(Call->CallId));
  1343. ConnMutex.Clear();
  1344. TransAbortConnection();
  1345. //
  1346. // Wait until only the call reference (and the reference added above)
  1347. // remains
  1348. //
  1349. while (RefCount.GetInteger() > 2)
  1350. {
  1351. SleepEx(1, 0);
  1352. }
  1353. ASSERT(IsDeleted());
  1354. TransClose();
  1355. //
  1356. // Ugly hack alert
  1357. //
  1358. SetNotDeleted();
  1359. ConnMutex.Request();
  1360. retval = ActiveCalls.Insert(IntToPtr(Call->CallId), Call);
  1361. ConnMutex.Clear();
  1362. //
  1363. // Don't remove the above reference
  1364. // the connection reference was removed by the thread
  1365. // that did called abort. We are just restoring that reference
  1366. //
  1367. if (retval == -1)
  1368. {
  1369. return RPC_S_OUT_OF_MEMORY;
  1370. }
  1371. return RPC_S_OK;
  1372. }
  1373. inline void SetFreshFromCacheFlag(void)
  1374. {
  1375. Flags.SetFlagUnsafe(FreshFromCache);
  1376. }
  1377. inline void ClearFreshFromCacheFlag(void)
  1378. {
  1379. Flags.ClearFlagUnsafe(FreshFromCache);
  1380. }
  1381. inline BOOL GetFreshFromCacheFlag(void)
  1382. {
  1383. return Flags.GetFlag(FreshFromCache);
  1384. }
  1385. static void
  1386. OsfDeleteIdleConnections (
  1387. void
  1388. );
  1389. RPC_STATUS
  1390. TurnOnOffKeepAlives (
  1391. IN BOOL TurnOn,
  1392. IN ULONG Timeout
  1393. );
  1394. private:
  1395. inline void
  1396. InitializeWireAuthId (
  1397. IN CLIENT_AUTH_INFO * ClientAuthInfo
  1398. )
  1399. {
  1400. if (ClientAuthInfo)
  1401. WireAuthId = (unsigned char) ClientAuthInfo->AuthenticationService;
  1402. else
  1403. WireAuthId = RPC_C_AUTHN_NONE;
  1404. }
  1405. };
  1406. inline void *
  1407. OSF_CCONNECTION::operator new (
  1408. size_t allocBlock,
  1409. unsigned int xtraBytes
  1410. )
  1411. {
  1412. I_RPC_HANDLE pvTemp = (I_RPC_HANDLE) new char[allocBlock + xtraBytes];
  1413. return(pvTemp);
  1414. }
  1415. #pragma optimize ("t", on)
  1416. inline void
  1417. OSF_CCONNECTION::MakeConnectionIdle (
  1418. )
  1419. {
  1420. LogEvent(SU_CCONN, EV_STOP, this, 0, 0, 1);
  1421. fIdle = 1;
  1422. }
  1423. inline void
  1424. OSF_CCONNECTION::MakeConnectionActive (
  1425. )
  1426. {
  1427. LogEvent(SU_CCONN, EV_START, this, 0, 0, 1);
  1428. fIdle = 0;
  1429. }
  1430. inline BOOL
  1431. OSF_CCONNECTION::IsIdle (
  1432. )
  1433. {
  1434. return fIdle;
  1435. }
  1436. inline void
  1437. OSF_CCONNECTION::NotifyCallDeleted (
  1438. )
  1439. {
  1440. }
  1441. inline void
  1442. OSF_CCONNECTION::IncSendSequenceNumber (
  1443. )
  1444. {
  1445. DceSecurityInfo.ReceiveSequenceNumber += 1;
  1446. }
  1447. inline void
  1448. OSF_CCONNECTION::IncReceiveSequenceNumber (
  1449. )
  1450. {
  1451. DceSecurityInfo.ReceiveSequenceNumber += 1;
  1452. }
  1453. inline ULONG
  1454. OSF_CCONNECTION::InquireSendSequenceNumber (
  1455. )
  1456. {
  1457. return DceSecurityInfo.SendSequenceNumber ;
  1458. }
  1459. inline ULONG
  1460. OSF_CCONNECTION::InquireReceiveSequenceNumber (
  1461. )
  1462. {
  1463. return DceSecurityInfo.ReceiveSequenceNumber ;
  1464. }
  1465. inline int
  1466. OSF_CCONNECTION::SupportedPContext (
  1467. IN int *PresentationContexts,
  1468. IN int NumberOfPresentationContexts,
  1469. OUT int *PresentationContextSupported
  1470. )
  1471. /*++
  1472. Return Value:
  1473. Non-zero will be returned if this connection supports the supplied
  1474. presentation context; otherwise, zero will be returned.
  1475. --*/
  1476. {
  1477. int i;
  1478. int Result;
  1479. for (i = 0; i < NumberOfPresentationContexts; i ++)
  1480. {
  1481. Result = Bindings.MemberP(PresentationContexts[i]);
  1482. if (Result)
  1483. {
  1484. *PresentationContextSupported = i;
  1485. break;
  1486. }
  1487. }
  1488. return Result;
  1489. }
  1490. inline UINT
  1491. OSF_CCONNECTION::InqMaximumFragmentLength (
  1492. )
  1493. /*++
  1494. Return Value:
  1495. The maximum fragment length negotiated for this connection will be
  1496. returned.
  1497. --*/
  1498. {
  1499. return(MaxFrag);
  1500. }
  1501. #pragma optimize("", on)
  1502. inline void
  1503. OSF_CCONNECTION::SetLastTimeUsedToNow (
  1504. )
  1505. /*++
  1506. Routine Description:
  1507. We the the last time that this connection was used to now.
  1508. --*/
  1509. {
  1510. LastTimeUsed = NtGetTickCount();
  1511. }
  1512. inline ULONG
  1513. OSF_CCONNECTION::InquireLastTimeUsed (
  1514. )
  1515. /*++
  1516. Return Value:
  1517. The last time this connection was used will be returned.
  1518. --*/
  1519. {
  1520. return(LastTimeUsed);
  1521. }
  1522. inline RPC_STATUS
  1523. OSF_CCALL::InqSecurityContext (
  1524. OUT void **SecurityContextHandle
  1525. )
  1526. {
  1527. *SecurityContextHandle = Connection->ClientSecurityContext.InqSecurityContext();
  1528. return RPC_S_OK;
  1529. }
  1530. inline RPC_STATUS
  1531. OSF_CCALL::InqWireIdForSnego (
  1532. OUT unsigned char *WireId
  1533. )
  1534. {
  1535. if ((Connection->ClientSecurityContext.AuthenticationLevel == RPC_C_AUTHN_LEVEL_NONE)
  1536. || (Connection->ClientSecurityContext.AuthenticationService == RPC_C_AUTHN_NONE))
  1537. return RPC_S_INVALID_BINDING;
  1538. return Connection->ClientSecurityContext.GetWireIdForSnego(WireId);
  1539. }
  1540. inline RPC_STATUS
  1541. OSF_CCALL::BindingHandleToAsyncHandle (
  1542. OUT void **AsyncHandle
  1543. )
  1544. {
  1545. if (pAsync == 0)
  1546. return RPC_S_INVALID_BINDING;
  1547. *AsyncHandle = pAsync;
  1548. return RPC_S_OK;
  1549. }
  1550. class OSF_BINDING : public MTSyntaxBinding
  1551. {
  1552. public:
  1553. OSF_BINDING (
  1554. IN RPC_SYNTAX_IDENTIFIER *InterfaceId,
  1555. IN TRANSFER_SYNTAX_STUB_INFO *TransferSyntaxInfo,
  1556. IN int CapabilitiesBitmap
  1557. ) : MTSyntaxBinding(InterfaceId, TransferSyntaxInfo, CapabilitiesBitmap)
  1558. {
  1559. }
  1560. inline void SetNextBinding(OSF_BINDING *Next)
  1561. {
  1562. MTSyntaxBinding::SetNextBinding(Next);
  1563. }
  1564. inline OSF_BINDING *GetNextBinding(void)
  1565. {
  1566. return (OSF_BINDING *)(MTSyntaxBinding::GetNextBinding());
  1567. }
  1568. inline int CompareWithTransferSyntax (IN const p_syntax_id_t *TransferSyntax)
  1569. {
  1570. return CompareWithTransferSyntax ((RPC_SYNTAX_IDENTIFIER *)TransferSyntax);
  1571. }
  1572. inline int CompareWithTransferSyntax (IN const RPC_SYNTAX_IDENTIFIER *TransferSyntax)
  1573. {
  1574. return MTSyntaxBinding::CompareWithTransferSyntax ((RPC_SYNTAX_IDENTIFIER *)TransferSyntax);
  1575. }
  1576. };
  1577. NEW_SDICT(OSF_BINDING);
  1578. NEW_SDICT(OSF_CCONNECTION);
  1579. enum MPX_TYPES
  1580. {
  1581. mpx_unknown,
  1582. mpx_yes,
  1583. mpx_no
  1584. };
  1585. NEW_SDICT(RPC_TOKEN);
  1586. class OSF_CASSOCIATION : public REFERENCED_OBJECT
  1587. /*++
  1588. Class Description:
  1589. Fields:
  1590. MaintainContext - Contains a flag indicating whether or not this
  1591. association needs to keep at least one connection open with
  1592. the server if at all possible. A non-zero value indicates that
  1593. at least one connection should be kept open.
  1594. CallIdCounter - Contains an interlocked integer used to allocate
  1595. unique call identifiers.
  1596. BindHandleCount - Counts the number of OSF_BINDING_HANDLEs using
  1597. this association. This particular variable is operated
  1598. with interlocks. However, adding a refcount if you don't have
  1599. one (as in FindOrCreateAssociation - through the global data
  1600. structure) requires holding AssocDictMutex.
  1601. --*/
  1602. {
  1603. friend class OSF_CCONNECTION;
  1604. friend class OSF_CCALL;
  1605. friend class OSF_BINDING_HANDLE;
  1606. private:
  1607. DCE_BINDING * DceBinding;
  1608. INTERLOCKED_INTEGER BindHandleCount;
  1609. ULONG AssocGroupId;
  1610. OSF_BINDING_DICT Bindings;
  1611. OSF_CCONNECTION_DICT ActiveConnections;
  1612. TRANS_INFO *TransInfo ;
  1613. unsigned char * SecondaryEndpoint;
  1614. int Key;
  1615. UINT OpenConnectionCount;
  1616. UINT ConnectionsDoingBindCount;
  1617. BOOL fPossibleServerReset;
  1618. UINT MaintainContext;
  1619. ULONG CallIdCounter;
  1620. MUTEX AssociationMutex;
  1621. BOOL AssociationValid;
  1622. // in some cases we will decide that the association is dead,
  1623. // and we will mark it as such so that other calls can
  1624. // quickly fail instead of banging against a dead server.
  1625. // The error with which the association was shutdown is
  1626. // stored here. Callers that implement quick failure detection
  1627. // can read it off here. This is valid only if
  1628. // AssociationValid == FALSE.
  1629. RPC_STATUS AssociationShutdownError;
  1630. BOOL DontLinger;
  1631. BOOL ResolverHintInitialized;
  1632. // protected by the AssociationMutex
  1633. BOOL fIdleConnectionCleanupNeeded;
  1634. int FailureCount;
  1635. MPX_TYPES fMultiplex;
  1636. unsigned long SavedDrep;
  1637. RPC_TOKEN_DICT TokenDict;
  1638. union
  1639. {
  1640. struct
  1641. {
  1642. // TRUE if this is an association without binding handle
  1643. // references to it (i.e. it is lingered), FALSE
  1644. // otherwise. Protected by the AssocDictMutex
  1645. BOOL fAssociationLingered;
  1646. // The timestamp for garbage collecting this item. Defined
  1647. // only if fAssociationLingered == TRUE. Protected by the
  1648. // AssocDictMutex
  1649. DWORD Timestamp;
  1650. } Linger;
  1651. // this arm of the union is used only during destruction - never use
  1652. // it outside
  1653. OSF_CASSOCIATION *NextAssociation;
  1654. };
  1655. public:
  1656. OSF_CASSOCIATION (
  1657. IN DCE_BINDING * DceBinding,
  1658. IN TRANS_INFO *TransInfo,
  1659. IN OUT RPC_STATUS * RpcStatus
  1660. );
  1661. ~OSF_CASSOCIATION (
  1662. );
  1663. public:
  1664. #if 0
  1665. void
  1666. CleanupAuthenticatedConnections(
  1667. IN CLIENT_AUTH_INFO *ClientAuthInfo
  1668. );
  1669. #endif
  1670. void
  1671. UnBind ( // Decrement the BindingCount, and clean up the
  1672. // association if it reaches zero.
  1673. );
  1674. RPC_STATUS
  1675. FindOrCreateOsfBinding (
  1676. IN PRPC_CLIENT_INTERFACE RpcInterfaceInformation,
  1677. IN RPC_MESSAGE *Message,
  1678. OUT int *NumberOfBindings,
  1679. IN OUT OSF_BINDING *BindingsForThisInterface[]
  1680. );
  1681. BOOL
  1682. DoesBindingForInterfaceExist (
  1683. IN PRPC_CLIENT_INTERFACE RpcInterfaceInformation
  1684. );
  1685. RPC_STATUS
  1686. AllocateCCall (
  1687. IN OSF_BINDING_HANDLE *BindingHandle,
  1688. IN PRPC_MESSAGE Message,
  1689. IN CLIENT_AUTH_INFO * ClientAuthInfo,
  1690. OUT OSF_CCALL ** CCall,
  1691. OUT BOOL *fBindingHandleReferenceRemoved
  1692. );
  1693. private:
  1694. RPC_STATUS
  1695. ProcessBindAckOrNak (
  1696. IN rpcconn_common *Buffer,
  1697. IN UINT BufferLength,
  1698. IN OSF_CCONNECTION *CConnection,
  1699. IN OSF_CCALL *CCall,
  1700. OUT ULONG *NewGroupId,
  1701. OUT OSF_BINDING **BindingNegotiated,
  1702. OUT FAILURE_COUNT_STATE *fFailureCountExceeded OPTIONAL
  1703. );
  1704. OSF_CCONNECTION *
  1705. LookForExistingConnection (
  1706. IN OSF_BINDING_HANDLE *BindingHandle,
  1707. IN BOOL fExclusive,
  1708. IN CLIENT_AUTH_INFO *ClientAuthInfo,
  1709. IN int *PresentContext,
  1710. IN int NumberOfPresentationContexts,
  1711. OUT int *PresentationContextSupported,
  1712. OUT OSF_CCALL_STATE *InitialCallState,
  1713. IN BOOL fNonCausal
  1714. );
  1715. inline void
  1716. ClearIdleConnectionCleanupFlag (
  1717. void
  1718. )
  1719. {
  1720. AssociationMutex.VerifyOwned();
  1721. if (fIdleConnectionCleanupNeeded)
  1722. {
  1723. fIdleConnectionCleanupNeeded = FALSE;
  1724. if (InterlockedDecrement(&PeriodicGarbageCollectItems) == 0)
  1725. {
  1726. #if defined (RPC_GC_AUDIT)
  1727. DbgPrintEx(77, DPFLTR_WARNING_LEVEL, "%d (0x%X) PeriodicGarbageCollectItems dropped to 0 (a)\n",
  1728. GetCurrentProcessId(), GetCurrentProcessId());
  1729. #endif
  1730. }
  1731. }
  1732. }
  1733. public:
  1734. int
  1735. CompareWithDceBinding (
  1736. IN DCE_BINDING * DceBinding,
  1737. OUT BOOL *fOnlyEndpointDifferent
  1738. );
  1739. //
  1740. // Note, whoever calls this routine must have already
  1741. // requested the AssociationDictMutex.
  1742. //
  1743. void
  1744. IncrementCount (
  1745. void
  1746. )
  1747. {
  1748. LogEvent(SU_CASSOC, EV_INC, this, (PVOID)2, BindHandleCount.GetInteger(), 1, 0);
  1749. BindHandleCount.Increment();
  1750. }
  1751. void
  1752. ShutdownRequested (
  1753. IN RPC_STATUS AssociationShutdownError OPTIONAL,
  1754. IN OSF_CCONNECTION *ExemptConnection OPTIONAL
  1755. );
  1756. inline OSF_BINDING *
  1757. FindBinding (
  1758. IN int PresentContext
  1759. )
  1760. {
  1761. return(Bindings.Find(PresentContext));
  1762. }
  1763. virtual RPC_STATUS
  1764. ToStringBinding (
  1765. OUT RPC_CHAR * * StringBinding,
  1766. IN RPC_UUID * ObjectUuid
  1767. );
  1768. OSF_CCONNECTION *
  1769. FindIdleConnection (
  1770. void
  1771. );
  1772. void
  1773. MaintainingContext (
  1774. );
  1775. DCE_BINDING *
  1776. DuplicateDceBinding (
  1777. );
  1778. BOOL
  1779. IsValid (
  1780. );
  1781. BOOL
  1782. ConnectionAborted (
  1783. IN OSF_CCONNECTION *Connection
  1784. );
  1785. void
  1786. NotifyConnectionOpen (
  1787. );
  1788. void
  1789. NotifyConnectionClosed (
  1790. );
  1791. void NotifyConnectionBindInProgress (
  1792. void
  1793. );
  1794. void NotifyConnectionBindCompleted (
  1795. void
  1796. );
  1797. void * operator new (
  1798. size_t allocBlock,
  1799. unsigned int xtraBytes
  1800. );
  1801. int
  1802. CompareResolverHint (
  1803. void *Hint
  1804. );
  1805. void *
  1806. InqResolverHint (
  1807. );
  1808. void
  1809. SetResolverHint (
  1810. void *Hint
  1811. );
  1812. void
  1813. FreeResolverHint (
  1814. void *Hint
  1815. );
  1816. inline BOOL
  1817. IsResolverHintSynchronizationNeeded (
  1818. void
  1819. );
  1820. inline void
  1821. ResetAssociation (
  1822. )
  1823. {
  1824. AssocGroupId = 0;
  1825. if (ResolverHintInitialized)
  1826. {
  1827. ResolverHintInitialized = FALSE;
  1828. FreeResolverHint(InqResolverHint());
  1829. }
  1830. }
  1831. BOOL
  1832. IsAssociationReset ( void )
  1833. {
  1834. return (AssocGroupId == 0);
  1835. }
  1836. RPC_STATUS
  1837. FindOrCreateToken (
  1838. IN HANDLE hToken,
  1839. IN LUID *pLuid,
  1840. OUT RPC_TOKEN **ppToken,
  1841. OUT BOOL *pfTokenFound
  1842. );
  1843. void
  1844. ReferenceToken(
  1845. IN RPC_TOKEN *pToken
  1846. );
  1847. void
  1848. DereferenceToken(
  1849. IN RPC_TOKEN *pToken
  1850. );
  1851. void
  1852. CleanupConnectionList(
  1853. IN RPC_TOKEN *pToken
  1854. );
  1855. static void
  1856. OsfDeleteLingeringAssociations (
  1857. void
  1858. );
  1859. inline BOOL
  1860. GetDontLingerState (
  1861. void
  1862. )
  1863. {
  1864. return DontLinger;
  1865. }
  1866. inline void
  1867. SetDontLingerState (
  1868. IN BOOL DontLinger
  1869. )
  1870. {
  1871. ASSERT(DontLinger == TRUE);
  1872. ASSERT(this->DontLinger == FALSE);
  1873. this->DontLinger = DontLinger;
  1874. }
  1875. };
  1876. inline int
  1877. OSF_CASSOCIATION::CompareResolverHint (
  1878. void *Hint
  1879. )
  1880. {
  1881. RPC_CONNECTION_TRANSPORT *ClientInfo =
  1882. (RPC_CONNECTION_TRANSPORT *) TransInfo->InqTransInfo();
  1883. if (ClientInfo->CompareResolverHint)
  1884. {
  1885. return ClientInfo->CompareResolverHint(TransResolverHint(), Hint);
  1886. }
  1887. else
  1888. {
  1889. return RpcpMemoryCompare(TransResolverHint(), Hint, ClientInfo->ResolverHintSize);
  1890. }
  1891. }
  1892. inline void *
  1893. OSF_CASSOCIATION::InqResolverHint (
  1894. )
  1895. {
  1896. return TransResolverHint();
  1897. }
  1898. inline void
  1899. OSF_CASSOCIATION::SetResolverHint (
  1900. void *Hint
  1901. )
  1902. {
  1903. RPC_CONNECTION_TRANSPORT *ClientInfo =
  1904. (RPC_CONNECTION_TRANSPORT *) TransInfo->InqTransInfo();
  1905. if (ClientInfo->CopyResolverHint)
  1906. {
  1907. if (TransResolverHint() != Hint)
  1908. {
  1909. ClientInfo->CopyResolverHint(TransResolverHint(),
  1910. Hint,
  1911. TRUE // SourceWillBeAbandoned
  1912. );
  1913. }
  1914. }
  1915. else
  1916. {
  1917. RpcpMemoryCopy(TransResolverHint(), Hint, ClientInfo->ResolverHintSize);
  1918. }
  1919. }
  1920. inline void
  1921. OSF_CASSOCIATION::FreeResolverHint (
  1922. void *Hint
  1923. )
  1924. {
  1925. RPC_CONNECTION_TRANSPORT *ClientInfo =
  1926. (RPC_CONNECTION_TRANSPORT *) TransInfo->InqTransInfo();
  1927. if (ClientInfo->FreeResolverHint)
  1928. {
  1929. ClientInfo->FreeResolverHint(Hint);
  1930. }
  1931. }
  1932. BOOL
  1933. OSF_CASSOCIATION::IsResolverHintSynchronizationNeeded (
  1934. void
  1935. )
  1936. {
  1937. RPC_CONNECTION_TRANSPORT *ClientInfo =
  1938. (RPC_CONNECTION_TRANSPORT *) TransInfo->InqTransInfo();
  1939. return (ClientInfo->FreeResolverHint != NULL);
  1940. }
  1941. inline void *
  1942. OSF_CASSOCIATION::operator new (
  1943. size_t allocBlock,
  1944. unsigned int xtraBytes
  1945. )
  1946. {
  1947. I_RPC_HANDLE pvTemp = (I_RPC_HANDLE) new char[allocBlock + xtraBytes];
  1948. return(pvTemp);
  1949. }
  1950. inline BOOL
  1951. OSF_CASSOCIATION::IsValid (
  1952. )
  1953. {
  1954. return AssociationValid ;
  1955. }
  1956. inline void
  1957. OSF_CASSOCIATION::MaintainingContext (
  1958. )
  1959. /*++
  1960. Routine Description:
  1961. This routine is used to indicate that a binding handle using this
  1962. association is maintaining context with the server. This means
  1963. that at least one connection for this association must always be
  1964. open.
  1965. --*/
  1966. {
  1967. MaintainContext = 1;
  1968. }
  1969. inline DCE_BINDING *
  1970. OSF_CASSOCIATION::DuplicateDceBinding (
  1971. )
  1972. {
  1973. return(DceBinding->DuplicateDceBinding());
  1974. }
  1975. inline ULONG
  1976. OSF_CCONNECTION::GetAssocGroupId (
  1977. )
  1978. {
  1979. return Association->AssocGroupId ;
  1980. }
  1981. inline void
  1982. OSF_CCONNECTION::WaitForSend (
  1983. )
  1984. {
  1985. while (ConnectionReady == 0)
  1986. {
  1987. //
  1988. // We need a listening thread
  1989. // so the send can complete
  1990. //
  1991. Association->TransInfo->CreateThread();
  1992. Sleep(10);
  1993. }
  1994. ASSERT(ConnectionReady == 1);
  1995. ConnectionReady = 0;
  1996. }
  1997. inline void
  1998. OSF_CCONNECTION::DeleteConnection (
  1999. )
  2000. {
  2001. if (fExclusive == 0)
  2002. {
  2003. TransAbortConnection();
  2004. }
  2005. Delete();
  2006. }
  2007. inline RPC_CHAR *OSF_CCONNECTION::InqEndpoint(void)
  2008. {
  2009. return Association->DceBinding->InqEndpoint();
  2010. }
  2011. inline RPC_CHAR *OSF_CCONNECTION::InqNetworkAddress(void)
  2012. {
  2013. return Association->DceBinding->InqNetworkAddress();
  2014. }
  2015. inline void
  2016. OSF_BINDING_HANDLE::Unbind ()
  2017. {
  2018. BOOL fMutexTaken;
  2019. // try to take the two mutexes, but if fail on the second, release
  2020. // the first as well and retry, because there is a potential
  2021. // deadlock condition for which this is a workaround
  2022. while (TRUE)
  2023. {
  2024. AssocDictMutex->Request();
  2025. fMutexTaken = Association->AssociationMutex.TryRequest();
  2026. if (fMutexTaken)
  2027. break;
  2028. else
  2029. {
  2030. AssocDictMutex->Clear();
  2031. Sleep(10);
  2032. }
  2033. }
  2034. if (pToken)
  2035. {
  2036. Association->DereferenceToken(pToken);
  2037. pToken = 0;
  2038. }
  2039. // unbind will clear the association dict mutex
  2040. // and the association mutex
  2041. Association->UnBind();
  2042. Association = 0;
  2043. }
  2044. RPC_STATUS
  2045. LoadableTransportClientInfo (
  2046. IN RPC_CHAR * DllName,
  2047. IN RPC_CHAR * RpcProtocolSequence,
  2048. OUT TRANS_INFO * *ClientTransInfo
  2049. );
  2050. TRANS_INFO *
  2051. GetLoadedClientTransportInfoFromId (
  2052. IN unsigned short TransportId
  2053. );
  2054. RPC_STATUS SetAuthInformation (
  2055. IN RPC_BINDING_HANDLE BindingHandle,
  2056. IN CLIENT_AUTH_INFO *AuthInfo
  2057. );
  2058. // --------------------------------------------------------------------
  2059. #endif // __OSFCLNT_HXX__