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.

2938 lines
68 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. // This data member has very rich semantics. Named pipes of
  228. // course are a special beast, and for them we do a bunch of
  229. // special magic. If this is not a named pipe binding handle,
  230. // NPType will be nptNotNamedPipe. However, if it is a named pipe
  231. // it will be one of nptLocalStatic, nptRemoteStatic,
  232. // nptLocalDynamic and nptRemoteDynamic. We do three things
  233. // differently for named pipes:
  234. // A. Determine when an existing connection can be used for a new
  235. // binding handle. This is needed because while we know that
  236. // all binding handles on the association are either static
  237. // or dynamic on the named pipe transport security level (this
  238. // is part of the association comparison logic), the different
  239. // binding handles may have different identities hanging off
  240. // them. Therefore you need to open new connections, unless
  241. // the identity tracking is dynamic and the connection is
  242. // exclusive
  243. // B. Swap token on Open. This is needed because we may do the
  244. // open from a worker thread which does not have the identity
  245. // used for the binding handle. For static tracking, we need this
  246. // even when opening from the client thread.
  247. // C. Swap token on Write. This is needed when dynamic tracking
  248. // is used to prevent impersontation from the server resulting in
  249. // the process identity vs. the caller identity when the writes
  250. // are done on a worker thread.
  251. // Depending on the local/remote and static/dynamic settings, we
  252. // have the following table of what we do when
  253. // Identity
  254. // Tracking Local Remote
  255. // ---------------------------------------------------
  256. // Static A, B A, B
  257. // Dynamic B, C, maybe A A, B
  258. NamedPipeType NPType;
  259. BOOL TransAuthInitialized;
  260. BOOL fDynamicEndpoint;
  261. OSF_BINDING_HANDLE (
  262. IN OUT RPC_STATUS * RpcStatus
  263. );
  264. ~OSF_BINDING_HANDLE (
  265. );
  266. virtual RPC_STATUS
  267. NegotiateTransferSyntax (
  268. IN OUT PRPC_MESSAGE Message
  269. );
  270. virtual RPC_STATUS
  271. GetBuffer (
  272. IN OUT PRPC_MESSAGE Message,
  273. IN UUID *ObjectUuid
  274. );
  275. virtual RPC_STATUS
  276. BindingCopy (
  277. OUT BINDING_HANDLE * * DestinationBinding,
  278. IN UINT MaintainContext
  279. );
  280. virtual RPC_STATUS
  281. BindingFree (
  282. );
  283. virtual RPC_STATUS
  284. PrepareBindingHandle (
  285. IN TRANS_INFO * TransportInterface,
  286. IN DCE_BINDING * DceBinding
  287. );
  288. virtual RPC_STATUS
  289. ToStringBinding (
  290. OUT RPC_CHAR * * StringBinding
  291. );
  292. virtual RPC_STATUS
  293. ResolveBinding (
  294. IN RPC_CLIENT_INTERFACE * RpcClientInterface
  295. );
  296. virtual RPC_STATUS
  297. BindingReset (
  298. );
  299. virtual RPC_STATUS
  300. InquireTransportType(
  301. OUT UINT *Type
  302. )
  303. { *Type = TRANSPORT_TYPE_CN; return(RPC_S_OK); }
  304. virtual ULONG
  305. MapAuthenticationLevel (
  306. IN ULONG AuthenticationLevel
  307. );
  308. virtual void
  309. AddReference (
  310. )
  311. {
  312. BindingMutex.Request();
  313. ReferenceCount++;
  314. BindingMutex.Clear();
  315. }
  316. RPC_STATUS
  317. AllocateCCall (
  318. OUT OSF_CCALL * * CCall,
  319. IN PRPC_MESSAGE Message,
  320. OUT BOOL *Retry
  321. );
  322. RPC_STATUS
  323. AddRecursiveEntry (
  324. IN OSF_CCALL * CCall,
  325. IN PRPC_CLIENT_INTERFACE RpcInterfaceInformation
  326. );
  327. void
  328. RemoveRecursiveCall (
  329. IN OSF_CCALL * CCall
  330. );
  331. OSF_CASSOCIATION *
  332. TheAssociation (
  333. ) {return(Association);}
  334. OSF_CASSOCIATION *
  335. FindOrCreateAssociation (
  336. IN DCE_BINDING * DceBinding,
  337. IN TRANS_INFO * TransInfo,
  338. IN RPC_CLIENT_INTERFACE *InterfaceInfo
  339. );
  340. RPC_STATUS
  341. AcquireCredentialsForTransport (
  342. );
  343. BOOL
  344. SwapToken (
  345. HANDLE *OldToken
  346. );
  347. void Unbind ();
  348. virtual RPC_STATUS
  349. SetTransportOption( unsigned long option,
  350. ULONG_PTR optionValue );
  351. virtual RPC_STATUS
  352. InqTransportOption( unsigned long option,
  353. ULONG_PTR * pOptionValue );
  354. };
  355. const unsigned int BindingListPresent = 1;
  356. class OSF_CCONNECTION ;
  357. enum CANCEL_STATE {
  358. CANCEL_NOTREGISTERED = 0,
  359. CANCEL_INFINITE,
  360. CANCEL_NOTINFINITE
  361. };
  362. class OSF_CCALL : public CCALL
  363. /*++
  364. Class Description:
  365. This class encapsulates an RPC call.
  366. Fields:
  367. PresentationContext - This field is only valid when there is a remote
  368. procedure call in progress on this connection; it contains the
  369. presentation context for the call.
  370. DispatchTableCallback - This field is only valid when there is a remote
  371. procedure call in progress on this connection; it contains the
  372. dispatch table to use for callbacks.
  373. Association - Contains a pointer to the association which owns this
  374. connection.
  375. TokenLength - Contains the maximum size of a token for the security
  376. package being used by this connection; we need to keep track of
  377. this for the third leg authentication case.
  378. --*/
  379. {
  380. //
  381. // This class will only access the AssociationKey member.
  382. //
  383. friend class OSF_CASSOCIATION;
  384. friend class OSF_CCONNECTION;
  385. friend class OSF_BINDING_HANDLE;
  386. friend class OSF_CCALL_AVRF;
  387. public:
  388. OSF_CCALL_STATE CurrentState ;
  389. private:
  390. OSF_CCONNECTION *Connection ;
  391. OSF_BINDING_HANDLE *BindingHandle;
  392. int CallbackLevel;
  393. // don't access the struct members directly - only through
  394. // the access functions - this will ensure that the
  395. // contents of the struct is properly checked. Async first
  396. // calls on new connection have both elements valid if there
  397. // are no preferences. Since this is the only case where
  398. // this condition is true, we can use it as a flag.
  399. // If AvailableBindingsList is set, the elements in it carry a refcount
  400. // and SelectedBinding doesn't. If AvailableBindingsList is not set, then
  401. // SelectedBinding carries a refcount.
  402. struct
  403. {
  404. // NULL if no binding is selected
  405. OSF_BINDING *SelectedBinding;
  406. // this is the list of differning only by transfer syntax
  407. // bindings this call can use. It can have one or more
  408. // elements.
  409. // This may be NULL if the call doesn't need a list
  410. OSF_BINDING *AvailableBindingsList;
  411. } Bindings;
  412. void *CurrentBuffer ;
  413. BOOL fDataLengthNegotiated;
  414. int CurrentOffset ;
  415. ULONG CurrentBufferLength ;
  416. ULONG CallId;
  417. UINT RcvBufferLength ;
  418. BOOL FirstSend ;
  419. PRPC_DISPATCH_TABLE DispatchTableCallback;
  420. UINT MaximumFragmentLength;
  421. // starts from 0, and set to non-zero if security is used after
  422. // negotiating the bind
  423. UINT MaxSecuritySize ;
  424. UINT MaxDataLength;
  425. int ProcNum ;
  426. unsigned char *ReservedForSecurity ;
  427. UINT SecBufferLength;
  428. // When the call is created, set to 0, because we don't know whether
  429. // there is object UUID or not. During GetBuffer we will know, and then
  430. // we will set it properly. Starting from 0 allows the bind and GetBuffer
  431. // threads (if different) to check and to synchronize the updating of the
  432. // max fragment size, since it depends both on the object UUID and
  433. // the security negotiation
  434. UINT HeaderSize;
  435. UINT AdditionalSpaceForSecurity;
  436. ULONG SavedHeaderSize;
  437. void * SavedHeader;
  438. void * LastBuffer ;
  439. EVENT SyncEvent ;
  440. UINT ActualBufferLength;
  441. UINT NeededLength;
  442. void *CallSendContext;
  443. INTERLOCKED_INTEGER fAdvanceCallCount;
  444. BOOL fPeerChoked;
  445. static const unsigned int IsPipeCallFlag = 0x01;
  446. static const unsigned int MaxSecuritySizeUpdated = 0x02;
  447. static const unsigned int IsAsyncPipeCall = 0x04;
  448. static const unsigned int FreeLastBuffer = 0x08;
  449. CompositeFlags Flags; // One of the above flags may be set.
  450. public:
  451. BOOL fLastSendComplete;
  452. MUTEX CallMutex ;
  453. int RecursiveCallsKey;
  454. // the size of the non-pipe data. This is what goes out
  455. // as AllocHint on the wire.
  456. ULONG AllocHint;
  457. //
  458. // Indicates the call stack. Whenever a request message is sent or
  459. // received, the stack is incremented. Likewise, whenever a response
  460. // message is sent or received, the stack is decremented.
  461. //
  462. int CallStack;
  463. BOOL fCallCancelled;
  464. CANCEL_STATE CancelState;
  465. private:
  466. QUEUE BufferQueue ;
  467. BOOL InReply;
  468. BOOL fChoked;
  469. OSF_CCALL (
  470. RPC_STATUS * pStatus
  471. );
  472. public:
  473. virtual~OSF_CCALL (
  474. );
  475. virtual RPC_STATUS
  476. NegotiateTransferSyntax (
  477. IN OUT PRPC_MESSAGE Message
  478. );
  479. virtual RPC_STATUS
  480. GetBuffer (
  481. IN OUT PRPC_MESSAGE Message,
  482. IN UUID *ObjectUuid = 0
  483. );
  484. RPC_STATUS
  485. GetBufferWithoutCleanup (
  486. IN OUT PRPC_MESSAGE Message,
  487. IN UUID *ObjectUuid
  488. );
  489. virtual RPC_STATUS
  490. SendReceive (
  491. IN OUT PRPC_MESSAGE Message
  492. );
  493. RPC_STATUS
  494. SendReceiveHelper (
  495. IN OUT PRPC_MESSAGE Message,
  496. OUT BOOL *fRetry
  497. );
  498. virtual RPC_STATUS
  499. Send (
  500. IN PRPC_MESSAGE Message
  501. );
  502. virtual RPC_STATUS
  503. Receive (
  504. IN PRPC_MESSAGE Message,
  505. IN UINT Size
  506. );
  507. virtual void
  508. FreeBuffer (
  509. IN PRPC_MESSAGE Message
  510. );
  511. virtual void
  512. FreePipeBuffer (
  513. IN PRPC_MESSAGE Message
  514. );
  515. virtual RPC_STATUS
  516. ReallocPipeBuffer (
  517. IN PRPC_MESSAGE Message,
  518. IN UINT NewSize
  519. );
  520. virtual RPC_STATUS
  521. AsyncSend (
  522. IN OUT PRPC_MESSAGE Message
  523. );
  524. virtual RPC_STATUS
  525. AsyncReceive (
  526. IN OUT PRPC_MESSAGE Message,
  527. IN UINT Size
  528. );
  529. virtual RPC_STATUS
  530. SetAsyncHandle (
  531. IN PRPC_ASYNC_STATE pAsync
  532. ) ;
  533. virtual void
  534. ProcessSendComplete (
  535. IN RPC_STATUS EventStatus,
  536. IN BUFFER Buffer
  537. );
  538. virtual RPC_STATUS
  539. CancelAsyncCall (
  540. IN BOOL fAbort
  541. );
  542. virtual void
  543. FreeObject (
  544. );
  545. RPC_STATUS
  546. SendHelper (
  547. IN PRPC_MESSAGE Message,
  548. OUT BOOL *fFirstSend
  549. );
  550. RPC_STATUS
  551. SendData (
  552. IN BUFFER Buffer
  553. );
  554. RPC_STATUS
  555. SendMoreData (
  556. IN BUFFER Buffer
  557. );
  558. RPC_STATUS
  559. ActuallyAllocateBuffer (
  560. OUT void * * Buffer,
  561. IN UINT BufferLength
  562. );
  563. void
  564. ActuallyFreeBuffer (
  565. IN void * Buffer
  566. );
  567. //
  568. // Actually perform the buffer allocation.
  569. //
  570. RPC_STATUS
  571. GetBufferDo (
  572. IN UINT culRequiredLength,
  573. OUT void * * ppBuffer,
  574. IN int fDataValid = 0,
  575. IN int DataLength = 0
  576. );
  577. void
  578. FreeBufferDo (
  579. IN void *Buffer
  580. );
  581. RPC_STATUS
  582. ActivateCall (
  583. IN OSF_BINDING_HANDLE *BindingHandle,
  584. IN OSF_BINDING *Binding,
  585. IN OSF_BINDING *AvailableBindingsList,
  586. IN ULONG CallIdToUse,
  587. IN OSF_CCALL_STATE InitialCallState,
  588. IN PRPC_DISPATCH_TABLE DispatchTable,
  589. IN OSF_CCONNECTION *CConnection
  590. );
  591. void
  592. FreeCCall (
  593. IN RPC_STATUS Status
  594. );
  595. RPC_STATUS
  596. SendCancelPDU(
  597. );
  598. RPC_STATUS
  599. SendOrphanPDU (
  600. );
  601. RPC_STATUS
  602. BindToServer (
  603. BOOL fAsyncBind
  604. );
  605. RPC_STATUS
  606. Cancel(
  607. void * ThreadHandle
  608. );
  609. RPC_STATUS
  610. InqWireIdForSnego (
  611. OUT unsigned char *WireId
  612. );
  613. RPC_STATUS
  614. BindingHandleToAsyncHandle (
  615. OUT void **AsyncHandle
  616. );
  617. RPC_STATUS
  618. InqMarshalledTargetInfo (
  619. OUT unsigned long *MarshalledTargetInfoLength,
  620. OUT unsigned char **MarshalledTargetinfo
  621. );
  622. // if fMultipleBindingsAvailable is set, the return value is a head of a linked
  623. // list. If fMultipleBindingsAvailable is FALSE, only the element in the return
  624. // value is meaningful
  625. inline OSF_BINDING *
  626. GetListOfAvaialbleBindings (
  627. OUT BOOL *fMultipleBindingsAvailable
  628. )
  629. {
  630. if (Bindings.AvailableBindingsList)
  631. {
  632. *fMultipleBindingsAvailable = TRUE;
  633. return Bindings.AvailableBindingsList;
  634. }
  635. else
  636. {
  637. *fMultipleBindingsAvailable = FALSE;
  638. return Bindings.SelectedBinding;
  639. }
  640. }
  641. RPC_STATUS
  642. BindCompleteNotify (
  643. IN p_result_t *OsfResult,
  644. IN int IndexOfPresentationContextAccepted,
  645. OUT OSF_BINDING **BindingNegotiated
  646. );
  647. inline void EnterCallback(void)
  648. {
  649. CallbackLevel ++;
  650. }
  651. inline void ExitCallback(void)
  652. {
  653. CallbackLevel --;
  654. }
  655. inline BOOL IsCallInCallback(void)
  656. {
  657. return CallbackLevel > 0;
  658. }
  659. inline void
  660. SetIsPipeCallFlag (
  661. void
  662. )
  663. {
  664. Flags.SetFlagInterlocked(IsPipeCallFlag);
  665. }
  666. inline BOOL
  667. GetIsPipeCallFlag (
  668. void
  669. )
  670. {
  671. return Flags.GetFlag(IsPipeCallFlag);
  672. }
  673. // currently not used
  674. inline void
  675. ClearIsPipeCallFlag (
  676. void
  677. )
  678. {
  679. Flags.ClearFlagUnsafe(IsPipeCallFlag);
  680. }
  681. inline void
  682. SetMaxSecuritySizeUpdatedFlag (
  683. void
  684. )
  685. {
  686. Flags.SetFlagInterlocked(MaxSecuritySizeUpdated);
  687. }
  688. inline BOOL
  689. GetMaxSecuritySizeUpdatedFlag (
  690. void
  691. )
  692. {
  693. return Flags.GetFlag(MaxSecuritySizeUpdated);
  694. }
  695. // currently not used
  696. inline void
  697. ClearMaxSecuritySizeUpdatedFlag (
  698. void
  699. )
  700. {
  701. Flags.ClearFlagUnsafe(MaxSecuritySizeUpdated);
  702. }
  703. inline void
  704. SetIsAsyncPipeCallFlag (
  705. void
  706. )
  707. {
  708. Flags.SetFlagInterlocked(IsAsyncPipeCall);
  709. }
  710. inline BOOL
  711. GetIsAsyncPipeCallFlag (
  712. void
  713. )
  714. {
  715. return Flags.GetFlag(IsAsyncPipeCall);
  716. }
  717. inline void
  718. SetFreeLastBufferFlag (
  719. void
  720. )
  721. {
  722. Flags.SetFlagInterlocked(FreeLastBuffer);
  723. }
  724. inline BOOL
  725. GetFreeLastBufferFlag (
  726. void
  727. )
  728. {
  729. return Flags.GetFlag(FreeLastBuffer);
  730. }
  731. // Returns TRUE if the call object is for an async pipe call that
  732. // is doing pulls and for which the notification is not armed.
  733. // The user will do another pull for the call.
  734. inline BOOL
  735. IsAsyncPipeCallBeforePull (
  736. void
  737. )
  738. {
  739. return (GetIsAsyncPipeCallFlag() // This is an async pipe call
  740. && CurrentState == Receiving // it is in the pull stage
  741. && NeededLength == 0); // and the notification is not armed.
  742. }
  743. private:
  744. void
  745. SendFault (
  746. IN RPC_STATUS Status,
  747. IN int DidNotExecute
  748. );
  749. #define MAX_ALLOC_Hint 16*1024
  750. RPC_STATUS
  751. EatAuthInfoFromPacket (
  752. IN rpcconn_request * Request,
  753. IN OUT UINT * RequestLength
  754. );
  755. BOOL
  756. ProcessReceivedPDU (
  757. IN void *Buffer,
  758. IN int BufferLength
  759. );
  760. RPC_STATUS
  761. GetCoalescedBuffer (
  762. IN PRPC_MESSAGE Message,
  763. IN BOOL BufferValid
  764. );
  765. RPC_STATUS
  766. SendAlterContextPDU (
  767. );
  768. RPC_STATUS
  769. GetCoalescedBuffer(
  770. IN PRPC_MESSAGE Message);
  771. RPC_STATUS
  772. FastSendReceive (
  773. IN OUT PRPC_MESSAGE Message,
  774. OUT BOOL *fRetry
  775. );
  776. RPC_STATUS
  777. SendNextFragment (
  778. IN unsigned char PacketType = rpc_request,
  779. IN BOOL fFirstSend = TRUE,
  780. OUT void **ReceiveBuffer = 0,
  781. OUT UINT *ReceivedLength = 0
  782. );
  783. RPC_STATUS
  784. ActuallyProcessPDU (
  785. IN rpcconn_common *Packet,
  786. IN UINT PacketLength,
  787. IN OUT PRPC_MESSAGE Message,
  788. IN BOOL fAsync = 0,
  789. OUT BOOL *pfSubmitReceive = NULL
  790. );
  791. RPC_STATUS
  792. ProcessResponse (
  793. IN rpcconn_response *Packet,
  794. IN PRPC_MESSAGE Message,
  795. OUT BOOL *pfSubmitReceive
  796. );
  797. RPC_STATUS
  798. ProcessRequestOrResponse (
  799. IN rpcconn_request *Request,
  800. IN UINT PacketLength,
  801. IN BOOL fRequest,
  802. IN PRPC_MESSAGE Message
  803. );
  804. RPC_STATUS
  805. DealWithCallback (
  806. IN rpcconn_request *Request,
  807. IN PRPC_MESSAGE Message
  808. );
  809. RPC_STATUS
  810. ReceiveReply (
  811. IN rpcconn_request *Request,
  812. IN PRPC_MESSAGE Message
  813. );
  814. void
  815. CallFailed (
  816. IN RPC_STATUS Status
  817. ) ;
  818. int
  819. QueueBuffer (
  820. IN void *Buffer,
  821. IN int BufferLength);
  822. BOOL
  823. IssueNotification (
  824. IN RPC_ASYNC_EVENT Event = RpcCallComplete
  825. );
  826. RPC_STATUS ReserveSpaceForSecurityIfNecessary (void);
  827. void UpdateObjectUUIDInfo (IN UUID *ObjectUuid);
  828. void UpdateMaxFragLength (const IN ULONG AuthnLevel);
  829. RPC_STATUS AutoRetryCall(IN OUT RPC_MESSAGE *Message, IN BOOL fSendReceivePath,
  830. IN OSF_BINDING_HANDLE *LocalBindingHandle, IN RPC_STATUS CurrentStatus,
  831. IN RPC_ASYNC_STATE *AsyncState OPTIONAL);
  832. void CleanupOldCallOnAutoRetry(IN PVOID Buffer, IN BOOL fSendReceivePath,
  833. IN RPC_STATUS CurrentStatus)
  834. {
  835. FreeBufferDo(Buffer);
  836. if (fSendReceivePath)
  837. FreeCCall(CurrentStatus);
  838. else
  839. {
  840. //
  841. // Remove the call reference, CCALL--
  842. //
  843. RemoveReference();
  844. }
  845. }
  846. OSF_BINDING *GetSelectedBinding(void)
  847. {
  848. ASSERT(Bindings.SelectedBinding != NULL);
  849. return Bindings.SelectedBinding;
  850. }
  851. OSF_BINDING *GetBindingList(void)
  852. {
  853. ASSERT(Bindings.AvailableBindingsList != NULL);
  854. return Bindings.AvailableBindingsList;
  855. }
  856. void *
  857. ActualBuffer (
  858. IN void *Buffer
  859. );
  860. RPC_STATUS
  861. CallCancelled (
  862. OUT PDWORD Timeout
  863. );
  864. RPC_STATUS
  865. RegisterCallForCancels (
  866. );
  867. void
  868. UnregisterCallForCancels (
  869. );
  870. void * operator new (
  871. size_t allocBlock,
  872. unsigned int xtraBytes
  873. );
  874. RPC_STATUS
  875. UpdateBufferSize (
  876. IN OUT void **Buffer,
  877. IN int CurrentBufferLength
  878. );
  879. inline BOOL
  880. fOkToAdvanceCall()
  881. {
  882. return (fAdvanceCallCount.Increment() == 2);
  883. }
  884. virtual RPC_STATUS
  885. InqSecurityContext (
  886. OUT void **SecurityContextHandle
  887. );
  888. static RPC_STATUS
  889. NegotiateTransferSyntaxAndGetBuffer (
  890. IN OUT PRPC_MESSAGE Message,
  891. IN RPC_SYNTAX_IDENTIFIER *OldTransferSyntax,
  892. IN UUID *ObjectUuid
  893. );
  894. inline ULONG
  895. GetBindingHandleTimeout (
  896. IN OSF_BINDING_HANDLE *BindingToUse
  897. )
  898. {
  899. RPC_STATUS RpcStatus;
  900. ULONG_PTR OptionValue;
  901. RpcStatus = BindingToUse->OSF_BINDING_HANDLE::InqTransportOption(
  902. RPC_C_OPT_CALL_TIMEOUT,
  903. &OptionValue);
  904. ASSERT(RpcStatus == RPC_S_OK);
  905. if (OptionValue == 0)
  906. return INFINITE;
  907. else
  908. return (ULONG) OptionValue;
  909. }
  910. inline RPC_STATUS
  911. GetStatusForTimeout (
  912. IN OSF_BINDING_HANDLE *BindingHandleToUse,
  913. IN RPC_STATUS Status,
  914. BOOL fBindingHandleTimeoutUsed
  915. )
  916. {
  917. if (Status == RPC_P_TIMEOUT)
  918. {
  919. if (fBindingHandleTimeoutUsed)
  920. {
  921. Status = RPC_S_CALL_CANCELLED;
  922. RpcpErrorAddRecord(EEInfoGCRuntime,
  923. Status,
  924. EEInfoDLGetStatusForTimeout10,
  925. RPC_P_TIMEOUT,
  926. GetBindingHandleTimeout(BindingHandle));
  927. }
  928. else
  929. {
  930. Status = RPC_S_CALL_FAILED_DNE;
  931. RpcpErrorAddRecord(EEInfoGCRuntime,
  932. Status,
  933. EEInfoDLGetStatusForTimeout20,
  934. (ULONG)RPC_P_TIMEOUT,
  935. (ULONG)RPC_C_SERVER_BIND_TIMEOUT);
  936. }
  937. }
  938. return Status;
  939. }
  940. inline ULONG
  941. GetEffectiveTimeoutForBind (
  942. IN OSF_BINDING_HANDLE *BindingToUse,
  943. OUT BOOL *fBindingHandleTimeoutUsed
  944. )
  945. {
  946. ULONG Timeout;
  947. Timeout = GetBindingHandleTimeout(BindingToUse);
  948. if (Timeout > RPC_C_SERVER_BIND_TIMEOUT)
  949. {
  950. Timeout = RPC_C_SERVER_BIND_TIMEOUT;
  951. *fBindingHandleTimeoutUsed = FALSE;
  952. }
  953. else
  954. {
  955. *fBindingHandleTimeoutUsed = TRUE;
  956. }
  957. return Timeout;
  958. }
  959. static const unsigned int VTHeaderSize = sizeof(rpc_sec_verification_trailer) + MAX_RPC_SEC_VT_ALIGN;
  960. int SizeVerificationTrailer (
  961. void
  962. );
  963. void AddVerificationTrailer (
  964. IN RPC_MESSAGE *RpcMessage
  965. );
  966. rpc_sec_verification_trailer_command *AddVerificationTrailerHeader (
  967. IN RPC_MESSAGE *RpcMessage
  968. );
  969. };
  970. inline void *
  971. OSF_CCALL::operator new (
  972. size_t allocBlock,
  973. unsigned int xtraBytes
  974. )
  975. {
  976. I_RPC_HANDLE pvTemp = (I_RPC_HANDLE) new char[allocBlock + xtraBytes];
  977. return(pvTemp);
  978. }
  979. inline void
  980. OSF_CCALL::FreeObject (
  981. )
  982. {
  983. if (AsyncStatus == RPC_S_ASYNC_CALL_PENDING)
  984. {
  985. AsyncStatus = RPC_S_CALL_FAILED;
  986. }
  987. FreeCCall(AsyncStatus);
  988. }
  989. inline RPC_STATUS
  990. OSF_CCALL::RegisterCallForCancels (
  991. )
  992. {
  993. RPC_STATUS Status;
  994. if (pAsync == 0)
  995. {
  996. Status = RegisterForCancels(this);
  997. if (Status != RPC_S_OK)
  998. {
  999. return Status;
  1000. }
  1001. if (ThreadGetRpcCancelTimeout() == RPC_C_CANCEL_INFINITE_TIMEOUT)
  1002. {
  1003. CancelState = CANCEL_INFINITE;
  1004. }
  1005. else
  1006. {
  1007. CancelState = CANCEL_NOTINFINITE;
  1008. }
  1009. }
  1010. return RPC_S_OK;
  1011. }
  1012. inline void
  1013. OSF_CCALL::UnregisterCallForCancels (
  1014. )
  1015. {
  1016. if (pAsync == 0)
  1017. {
  1018. EVAL_AND_ASSERT(RPC_S_OK == UnregisterForCancels());
  1019. }
  1020. }
  1021. inline void *
  1022. OSF_CCALL::ActualBuffer (
  1023. IN void *Buffer
  1024. )
  1025. {
  1026. ASSERT (HeaderSize != 0);
  1027. if (UuidSpecified)
  1028. {
  1029. Buffer = (char *) Buffer - sizeof(rpcconn_request) - sizeof(UUID);
  1030. }
  1031. else
  1032. {
  1033. Buffer = (char *) Buffer - sizeof(rpcconn_request);
  1034. }
  1035. return Buffer;
  1036. }
  1037. inline int
  1038. OSF_CCALL::QueueBuffer (
  1039. IN void *Buffer,
  1040. IN int BufferLength
  1041. )
  1042. {
  1043. RcvBufferLength += BufferLength;
  1044. return BufferQueue.PutOnQueue(Buffer, BufferLength);
  1045. }
  1046. NEW_SDICT2(OSF_CCALL, PVOID);
  1047. class OSF_CCALL_AVRF : public OSF_CCALL
  1048. /*++
  1049. Class Description:
  1050. This class overwrites an OSF_CCALL for use with RPC verifier.
  1051. Methods will perform some checks.
  1052. --*/
  1053. {
  1054. public:
  1055. OSF_CCALL_AVRF(RPC_STATUS __RPC_FAR * pStatus) : OSF_CCALL(pStatus) {}
  1056. RPC_STATUS
  1057. GetBuffer (
  1058. IN OUT PRPC_MESSAGE Message,
  1059. IN UUID *ObjectUuid
  1060. );
  1061. };
  1062. #define SYNC_CONN_FREE 0
  1063. #define SYNC_CONN_BUSY -1
  1064. #define ASYNC_CONN_BUSY -2
  1065. #define ASYNC_CONN_FREE -3
  1066. enum CONNECTION_STATES
  1067. {
  1068. ConnUninitialized,
  1069. ConnAborted,
  1070. ConnOpen
  1071. };
  1072. const unsigned int FreshFromCache = 4;
  1073. const unsigned int TransInitialized = 8;
  1074. const unsigned int NoAssociationShutdown = 16;
  1075. enum FAILURE_COUNT_STATE
  1076. {
  1077. FailureCountUnknown,
  1078. FailureCountNotExceeded,
  1079. FailureCountExceeded
  1080. };
  1081. typedef enum tagConnectionSupportHeaderSign
  1082. {
  1083. cshsDontKnow, // = 0
  1084. cshsUnconfirmedNo, // = 1
  1085. cshsYes, // = 2
  1086. cshsConfirmedNo // = 3
  1087. } ConnectionSupportHeaderSign;
  1088. const unsigned int ConnectionSupportHeaderSignMask = 3;
  1089. class OSF_CCONNECTION : public REFERENCED_OBJECT
  1090. /*++
  1091. Class Description:
  1092. This class encapsulates a transport connection. The transport
  1093. connection may be used by one or more RPC calls. Each RPC
  1094. call is encapsulated by an CALL object. This object may
  1095. be exclusively used by a call. Each connection is owned by
  1096. exacly one thread (ie: all calls on a connection have been
  1097. initiated by a single thread).
  1098. Fields:
  1099. Association: Pointer to the association object
  1100. ConnectionKey: Key to our entry in the dictionary of connections in
  1101. the association.
  1102. ThreadId: Thread Id of the thread owning this call.
  1103. DceSecurityInfo - Contains information necessary for DCE security to
  1104. work properly. This includes the association uuid (a different
  1105. value for each connection), and sequence numbers (both directions).
  1106. ThirdLegAuthNeeded - Contains a flag indicating whether or not third
  1107. leg authentication is needed; a non-zero value indicates that it
  1108. is needed.
  1109. ClientSecurityContext - Optionally contains the security context being
  1110. used for this connection.
  1111. AdditionalSpaceForSecurity - Contains the amount of space to save
  1112. for security in each buffer we allocate.
  1113. LastTimeUsed - Contains the time in seconds when this connection was
  1114. last used.
  1115. CurrentCall - The call on which we are currently **sending** data
  1116. ClientInfo - Contains the pointers to the loadable transport routines
  1117. for the transport type of this connection.
  1118. fConnectionAborted - If this field is non-zero it indicates that the
  1119. connection has been aborted, meaning that any attempts to send
  1120. or receive data on the connection will fail.
  1121. --*/
  1122. {
  1123. friend class OSF_CASSOCIATION;
  1124. friend class OSF_CCALL;
  1125. friend class OSF_BINDING_HANDLE;
  1126. friend class OSF_CCALL_AVRF;
  1127. private:
  1128. OSF_CASSOCIATION * Association;
  1129. OSF_CCALL *CurrentCall ;
  1130. int ConnectionKey;
  1131. CONNECTION_STATES State;
  1132. unsigned char WireAuthId;
  1133. unsigned short MaxFrag;
  1134. ULONG ThreadId ;
  1135. BOOL CachedCCallAvailable ;
  1136. ULONG MaxSavedHeaderSize;
  1137. OSF_CCALL *CachedCCall ;
  1138. ULONG SavedHeaderSize;
  1139. unsigned int ComTimeout ;
  1140. void * SavedHeader;
  1141. BOOL AdditionalLegNeeded;
  1142. ULONG LastTimeUsed;
  1143. UINT TokenLength;
  1144. UINT AdditionalSpaceForSecurity;
  1145. BOOL fIdle ;
  1146. BOOL fExclusive ;
  1147. BOOL fConnectionAborted;
  1148. // ConnectionSupportHeaderSign transitions are as follows
  1149. //
  1150. // cshsDontKnow
  1151. // |
  1152. // +------------------------+----------------------+
  1153. // | |
  1154. // cshsYes cshsUnconfirmedNo
  1155. // |
  1156. // cshsConfirmedNo
  1157. //
  1158. // We start with cshsDontKnow. If first bind returns that the server supports signing,
  1159. // we go to cshsYes. If we don't get this, we don't know for sure yet (it may be a
  1160. // downgrade attack), so we move to cshsUnconfirmedNo. The first call that succeeds
  1161. // will make that a cshsConfirmedNo. We know new server will blow away all calls that
  1162. // indicate client supports signing but isn't doing it so the first successful call
  1163. // with verification trailer indicates negotiation is completed.
  1164. // All transitions will be called from a single thread only, except cshsUnconfirmedNo ->
  1165. // cshsConfirmedNo. For the last transition, we must use interlocks as it potentially
  1166. // races with ClearFreshFromCacheFlag.
  1167. CompositeFlags Flags;
  1168. BITSET Bindings;
  1169. QUEUE CallQueue ;
  1170. MUTEX ConnMutex ;
  1171. OSF_CCALL_DICT2 ActiveCalls ;
  1172. SECURITY_CONTEXT ClientSecurityContext;
  1173. RPC_CONNECTION_TRANSPORT * ClientInfo;
  1174. union
  1175. {
  1176. void *ConnSendContext ;
  1177. OSF_CCONNECTION *NextConnection; // used to link connections in some case
  1178. } u;
  1179. DCE_SECURITY_INFO DceSecurityInfo;
  1180. void *BufferToFree;
  1181. BOOL ConnectionReady;
  1182. BOOL fSeparateConnection;
  1183. public:
  1184. OSF_CCONNECTION (
  1185. IN OSF_CASSOCIATION *Association,
  1186. IN RPC_CONNECTION_TRANSPORT * RpcClientInfo,
  1187. IN unsigned int Timeout,
  1188. IN CLIENT_AUTH_INFO * myAuthInfo,
  1189. IN BOOL fExclusive,
  1190. IN BOOL fSeparateConnection,
  1191. OUT RPC_STATUS * pStatus
  1192. );
  1193. virtual ~OSF_CCONNECTION (
  1194. );
  1195. virtual void
  1196. ProcessSendComplete (
  1197. IN RPC_STATUS EventStatus,
  1198. IN BUFFER Buffer
  1199. );
  1200. RPC_STATUS
  1201. TransInitialize (
  1202. IN RPC_CHAR *NetworkAddress,
  1203. IN RPC_CHAR *NetworkOptions
  1204. )
  1205. {
  1206. if (ClientInfo->Initialize)
  1207. {
  1208. return ClientInfo->Initialize(TransConnection(),
  1209. NetworkAddress,
  1210. NetworkOptions,
  1211. (fExclusive == 0));
  1212. }
  1213. return (RPC_S_OK);
  1214. }
  1215. void
  1216. TransInitComplete (
  1217. )
  1218. {
  1219. if (ClientInfo->InitComplete)
  1220. {
  1221. ClientInfo->InitComplete(TransConnection());
  1222. }
  1223. }
  1224. RPC_STATUS
  1225. TransOpen (
  1226. IN OSF_BINDING_HANDLE * BindingHandle,
  1227. IN RPC_CHAR * RpcProtocolSequence,
  1228. IN RPC_CHAR * NetworkAddress,
  1229. IN RPC_CHAR * Endpoint,
  1230. IN RPC_CHAR * NetworkOptions,
  1231. IN void *ResolverHint,
  1232. IN BOOL fHintInitialized,
  1233. IN ULONG Timeout
  1234. ) ;
  1235. RPC_STATUS
  1236. TransReceive (
  1237. OUT void * * Buffer,
  1238. OUT unsigned int * BufferLength,
  1239. IN ULONG Timeout
  1240. );
  1241. RPC_STATUS
  1242. TransSend (
  1243. IN OSF_BINDING_HANDLE * BindingHandle, OPTIONAL
  1244. IN void * Buffer,
  1245. IN unsigned int BufferLength,
  1246. IN BOOL fDisableShutdownCheck,
  1247. IN BOOL fDisableCancelCheck,
  1248. IN ULONG Timeout
  1249. );
  1250. #ifdef WIN96
  1251. RPC_STATUS
  1252. TransClose (
  1253. );
  1254. #endif
  1255. RPC_STATUS
  1256. TransSendReceive (
  1257. IN OSF_BINDING_HANDLE * BindingHandle, OPTIONAL
  1258. IN void * SendBuffer,
  1259. IN unsigned int SendBufferLength,
  1260. OUT void * * ReceiveBuffer,
  1261. OUT unsigned int * ReceiveBufferLength,
  1262. IN ULONG Timeout
  1263. );
  1264. RPC_STATUS
  1265. TransAsyncSend (
  1266. IN OSF_BINDING_HANDLE * BindingHandle, OPTIONAL
  1267. IN void * SendBuffer,
  1268. IN unsigned int SendBufferLength,
  1269. IN void *SendContext
  1270. ) ;
  1271. RPC_STATUS
  1272. TransAsyncReceive (
  1273. ) ;
  1274. RPC_STATUS
  1275. TransPostEvent (
  1276. IN PVOID Context
  1277. ) ;
  1278. void
  1279. TransAbortConnection (
  1280. );
  1281. void
  1282. TransClose (
  1283. );
  1284. unsigned int
  1285. TransMaximumSend (
  1286. );
  1287. unsigned int
  1288. GuessPacketLength (
  1289. );
  1290. void * operator new (
  1291. size_t allocBlock,
  1292. unsigned int xtraBytes
  1293. );
  1294. RPC_STATUS
  1295. TransGetBuffer (
  1296. OUT void * * Buffer,
  1297. IN UINT BufferLength
  1298. );
  1299. void
  1300. TransFreeBuffer (
  1301. IN void * Buffer
  1302. );
  1303. RPC_STATUS
  1304. TransReallocBuffer (
  1305. IN OUT void * * Buffer,
  1306. IN UINT OldSize,
  1307. IN UINT NewSize
  1308. );
  1309. RPC_STATUS
  1310. AllocateCCall (
  1311. OUT OSF_CCALL **CCall
  1312. );
  1313. RPC_STATUS
  1314. AddCall (
  1315. IN OSF_CCALL *CCall
  1316. );
  1317. void
  1318. FreeCCall (
  1319. IN OSF_CCALL *CCall,
  1320. IN RPC_STATUS Status,
  1321. IN ULONG ComTimeout
  1322. );
  1323. RPC_STATUS
  1324. OpenConnectionAndBind (
  1325. IN OSF_BINDING_HANDLE *BindingHandle,
  1326. IN ULONG Timeout,
  1327. IN BOOL fAlwaysNegotiateNDR20,
  1328. OUT FAILURE_COUNT_STATE *fFailureCountExceeded OPTIONAL
  1329. );
  1330. RPC_STATUS
  1331. ActuallyDoBinding (
  1332. IN OSF_CCALL *CCall,
  1333. IN ULONG MyAssocGroupId,
  1334. IN BOOL fNewConnection,
  1335. IN ULONG Timeout,
  1336. OUT OSF_BINDING **BindingNegotiated,
  1337. OUT BOOL *fPossibleAssociationReset,
  1338. OUT FAILURE_COUNT_STATE *fFailureCountExceeded OPTIONAL
  1339. );
  1340. RPC_STATUS
  1341. SendBindPacket (
  1342. IN OSF_BINDING_HANDLE * BindingHandle, OPTIONAL
  1343. IN BOOL fInitialPass,
  1344. IN OSF_CCALL *Call,
  1345. IN ULONG AssocGroup,
  1346. IN unsigned char PacketType,
  1347. IN ULONG Timeout,
  1348. IN BOOL fAsync = 1,
  1349. OUT rpcconn_common * * Buffer = 0,
  1350. OUT UINT * BufferLength = 0,
  1351. IN rpcconn_common * InputPacket = 0,
  1352. IN unsigned int InputPacketLength = 0
  1353. );
  1354. RPC_STATUS
  1355. MaybeDo3rdLegAuth (
  1356. IN void * Buffer,
  1357. IN UINT BufferLength
  1358. );
  1359. //
  1360. // Set the value of the max frag for the connection.
  1361. //
  1362. void
  1363. SetMaxFrag (
  1364. IN unsigned short max_xmit_frag,
  1365. IN unsigned short max_recv_frag
  1366. );
  1367. UINT
  1368. InqMaximumFragmentLength (
  1369. );
  1370. inline int
  1371. AddPContext (
  1372. IN int PresentContext
  1373. );
  1374. inline void
  1375. DeletePContext (
  1376. IN int PresentContext
  1377. );
  1378. int
  1379. SupportedPContext (
  1380. IN int *PresentationContexts,
  1381. IN int NumberOfPresentationContexts,
  1382. OUT int *PresentationContextSupported
  1383. );
  1384. RPC_STATUS
  1385. SupportedAuthInfo (
  1386. IN CLIENT_AUTH_INFO * ClientAuthInfo,
  1387. IN NamedPipeType NPType,
  1388. IN BOOL IsExclusiveConnection,
  1389. OUT BOOL *Supported
  1390. );
  1391. RPC_STATUS
  1392. SendFragment (
  1393. IN rpcconn_common *pFragment,
  1394. IN OSF_CCALL *CCall,
  1395. IN UINT LastFragmentFlag,
  1396. IN UINT HeaderSize,
  1397. IN UINT MaxSecuritySize,
  1398. IN UINT DataLength,
  1399. IN UINT MaximumFragmentLength,
  1400. IN unsigned char *ReservedForSecurity,
  1401. IN BOOL fAsync,
  1402. IN void *SendContext,
  1403. IN ULONG Timeout,
  1404. OUT void **ReceiveBuffer,
  1405. OUT UINT *ReceiveBufferLength
  1406. );
  1407. void
  1408. ProcessReceiveComplete (
  1409. IN RPC_STATUS EventStatus,
  1410. IN BUFFER Buffer,
  1411. IN UINT BufferLength
  1412. );
  1413. ULONG
  1414. InquireSendSequenceNumber (
  1415. );
  1416. ULONG
  1417. InquireReceiveSequenceNumber (
  1418. );
  1419. RPC_CHAR *InqEndpoint(void);
  1420. RPC_CHAR *InqNetworkAddress(void);
  1421. void
  1422. IncSendSequenceNumber (
  1423. );
  1424. inline void
  1425. IncReceiveSequenceNumber (
  1426. );
  1427. void
  1428. NotifyCallDeleted (
  1429. );
  1430. void
  1431. SetLastTimeUsedToNow (
  1432. );
  1433. ULONG
  1434. InquireLastTimeUsed (
  1435. );
  1436. ULONG
  1437. GetAssocGroupId (
  1438. );
  1439. void
  1440. ConnectionAborted (
  1441. IN RPC_STATUS Status,
  1442. IN BOOL fShutdownAssoc = 1
  1443. );
  1444. void
  1445. AdvanceToNextCall (
  1446. );
  1447. RPC_STATUS
  1448. AddActiveCall (
  1449. IN ULONG CallId,
  1450. IN OSF_CCALL *CCall
  1451. );
  1452. RPC_STATUS
  1453. DealWithAlterContextResp (
  1454. IN OSF_CCALL *CCall,
  1455. IN rpcconn_common *Packet,
  1456. IN int PacketLength,
  1457. IN OUT BOOL *AlterContextToNDR20IfNDR64Negotiated
  1458. );
  1459. void
  1460. MakeConnectionIdle (
  1461. );
  1462. void
  1463. MakeConnectionActive (
  1464. );
  1465. BOOL
  1466. IsIdle (
  1467. );
  1468. void
  1469. DeleteConnection (
  1470. );
  1471. BOOL IsExclusive (void)
  1472. {
  1473. return fExclusive;
  1474. }
  1475. RPC_STATUS
  1476. ValidateHeader(
  1477. rpcconn_common * Buffer,
  1478. unsigned long BufferLength
  1479. );
  1480. RPC_STATUS
  1481. FinishSecurityContextSetup (
  1482. IN OSF_CCALL *Call,
  1483. IN unsigned long AssocGroup,
  1484. OUT rpcconn_common * * Buffer,
  1485. OUT unsigned int * BufferLength,
  1486. IN ULONG Timeout
  1487. );
  1488. RPC_STATUS
  1489. CallCancelled (
  1490. OUT PDWORD Timeout
  1491. );
  1492. void
  1493. WaitForSend(
  1494. );
  1495. BOOL
  1496. MatchModifiedId (
  1497. LUID *pModifiedId
  1498. )
  1499. {
  1500. if (ClientSecurityContext.DefaultLogonId)
  1501. {
  1502. return FALSE;
  1503. }
  1504. return (FastCompareLUIDAligned(pModifiedId, &ClientSecurityContext.ModifiedId));
  1505. }
  1506. void
  1507. MaybeAdvanceToNextCall(
  1508. OSF_CCALL *Call
  1509. )
  1510. {
  1511. if (fExclusive == 0
  1512. && CurrentCall == Call)
  1513. {
  1514. AdvanceToNextCall();
  1515. }
  1516. }
  1517. inline void SetFreshFromCacheFlag(void)
  1518. {
  1519. Flags.SetFlagUnsafe(FreshFromCache);
  1520. }
  1521. inline void ClearFreshFromCacheFlag(void)
  1522. {
  1523. Flags.ClearFlagInterlocked(FreshFromCache);
  1524. }
  1525. inline BOOL GetFreshFromCacheFlag(void)
  1526. {
  1527. return Flags.GetFlag(FreshFromCache);
  1528. }
  1529. inline void SetTransInitializedFlag(void)
  1530. {
  1531. Flags.SetFlagUnsafe(TransInitialized);
  1532. }
  1533. inline void ClearTransInitializedFlag(void)
  1534. {
  1535. Flags.ClearFlagInterlocked(TransInitialized);
  1536. }
  1537. inline BOOL GetTransInitializedFlag(void)
  1538. {
  1539. return Flags.GetFlag(TransInitialized);
  1540. }
  1541. inline ConnectionSupportHeaderSign
  1542. GetConnectionSupportHeaderSign (
  1543. void
  1544. )
  1545. {
  1546. return (ConnectionSupportHeaderSign)Flags.GetFlag(ConnectionSupportHeaderSignMask);
  1547. }
  1548. inline void
  1549. SetConnectionSupportHeaderSignUnsafe (
  1550. ConnectionSupportHeaderSign NewConnectionSupportHeaderSign
  1551. )
  1552. {
  1553. Flags.SetFlagUnsafe(NewConnectionSupportHeaderSign);
  1554. }
  1555. inline void
  1556. SetConnectionSupportHeaderSignInterlocked (
  1557. ConnectionSupportHeaderSign NewConnectionSupportHeaderSign
  1558. )
  1559. {
  1560. Flags.SetFlagInterlocked(NewConnectionSupportHeaderSign);
  1561. }
  1562. inline void
  1563. InitConnectionSupportHeaderSign (
  1564. void
  1565. )
  1566. {
  1567. Flags.SetFlagUnsafe(cshsDontKnow);
  1568. }
  1569. inline void
  1570. SuccessfulResponseReceived (
  1571. void
  1572. )
  1573. {
  1574. if (GetConnectionSupportHeaderSign() == cshsUnconfirmedNo)
  1575. {
  1576. SetConnectionSupportHeaderSignInterlocked (cshsConfirmedNo);
  1577. }
  1578. }
  1579. static void
  1580. OsfDeleteIdleConnections (
  1581. void
  1582. );
  1583. RPC_STATUS
  1584. TurnOnOffKeepAlives (
  1585. IN BOOL TurnOn,
  1586. IN ULONG Timeout
  1587. );
  1588. inline BOOL
  1589. IsVerificationTrailerNecessary (
  1590. void
  1591. )
  1592. {
  1593. return ((ClientSecurityContext.AuthenticationLevel >= RPC_C_AUTHN_LEVEL_PKT_INTEGRITY)
  1594. && (InqNetworkAddress() != NULL)
  1595. && (*(InqNetworkAddress()) != 0)
  1596. );
  1597. }
  1598. inline BOOL
  1599. IsSChannel (
  1600. void
  1601. )
  1602. {
  1603. return (ClientSecurityContext.AuthenticationService == RPC_C_AUTHN_GSS_SCHANNEL);
  1604. }
  1605. private:
  1606. inline void
  1607. InitializeWireAuthId (
  1608. IN CLIENT_AUTH_INFO * ClientAuthInfo
  1609. )
  1610. {
  1611. if (ClientAuthInfo)
  1612. WireAuthId = (unsigned char) ClientAuthInfo->AuthenticationService;
  1613. else
  1614. WireAuthId = RPC_C_AUTHN_NONE;
  1615. }
  1616. };
  1617. inline void *
  1618. OSF_CCONNECTION::operator new (
  1619. size_t allocBlock,
  1620. unsigned int xtraBytes
  1621. )
  1622. {
  1623. I_RPC_HANDLE pvTemp = (I_RPC_HANDLE) new char[allocBlock + xtraBytes];
  1624. return(pvTemp);
  1625. }
  1626. #pragma optimize ("t", on)
  1627. inline void
  1628. OSF_CCONNECTION::MakeConnectionIdle (
  1629. )
  1630. {
  1631. LogEvent(SU_CCONN, EV_STOP, this, 0, 0, 1);
  1632. fIdle = 1;
  1633. }
  1634. inline void
  1635. OSF_CCONNECTION::MakeConnectionActive (
  1636. )
  1637. {
  1638. LogEvent(SU_CCONN, EV_START, this, 0, 0, 1);
  1639. fIdle = 0;
  1640. }
  1641. inline BOOL
  1642. OSF_CCONNECTION::IsIdle (
  1643. )
  1644. {
  1645. return fIdle;
  1646. }
  1647. inline void
  1648. OSF_CCONNECTION::NotifyCallDeleted (
  1649. )
  1650. {
  1651. }
  1652. inline void
  1653. OSF_CCONNECTION::IncSendSequenceNumber (
  1654. )
  1655. {
  1656. DceSecurityInfo.ReceiveSequenceNumber += 1;
  1657. }
  1658. inline void
  1659. OSF_CCONNECTION::IncReceiveSequenceNumber (
  1660. )
  1661. {
  1662. DceSecurityInfo.ReceiveSequenceNumber += 1;
  1663. }
  1664. inline ULONG
  1665. OSF_CCONNECTION::InquireSendSequenceNumber (
  1666. )
  1667. {
  1668. return DceSecurityInfo.SendSequenceNumber ;
  1669. }
  1670. inline ULONG
  1671. OSF_CCONNECTION::InquireReceiveSequenceNumber (
  1672. )
  1673. {
  1674. return DceSecurityInfo.ReceiveSequenceNumber ;
  1675. }
  1676. inline UINT
  1677. OSF_CCONNECTION::InqMaximumFragmentLength (
  1678. )
  1679. /*++
  1680. Return Value:
  1681. The maximum fragment length negotiated for this connection will be
  1682. returned.
  1683. --*/
  1684. {
  1685. return(MaxFrag);
  1686. }
  1687. #pragma optimize("", on)
  1688. inline void
  1689. OSF_CCONNECTION::SetLastTimeUsedToNow (
  1690. )
  1691. /*++
  1692. Routine Description:
  1693. We the the last time that this connection was used to now.
  1694. --*/
  1695. {
  1696. LastTimeUsed = NtGetTickCount();
  1697. }
  1698. inline ULONG
  1699. OSF_CCONNECTION::InquireLastTimeUsed (
  1700. )
  1701. /*++
  1702. Return Value:
  1703. The last time this connection was used will be returned.
  1704. --*/
  1705. {
  1706. return(LastTimeUsed);
  1707. }
  1708. inline RPC_STATUS
  1709. OSF_CCALL::InqSecurityContext (
  1710. OUT void **SecurityContextHandle
  1711. )
  1712. {
  1713. *SecurityContextHandle = Connection->ClientSecurityContext.InqSecurityContext();
  1714. return RPC_S_OK;
  1715. }
  1716. inline RPC_STATUS
  1717. OSF_CCALL::InqWireIdForSnego (
  1718. OUT unsigned char *WireId
  1719. )
  1720. {
  1721. if ((Connection->ClientSecurityContext.AuthenticationLevel == RPC_C_AUTHN_LEVEL_NONE)
  1722. || (Connection->ClientSecurityContext.AuthenticationService == RPC_C_AUTHN_NONE))
  1723. return RPC_S_INVALID_BINDING;
  1724. return Connection->ClientSecurityContext.GetWireIdForSnego(WireId);
  1725. }
  1726. inline RPC_STATUS
  1727. OSF_CCALL::BindingHandleToAsyncHandle (
  1728. OUT void **AsyncHandle
  1729. )
  1730. {
  1731. if (pAsync == 0)
  1732. return RPC_S_INVALID_BINDING;
  1733. *AsyncHandle = pAsync;
  1734. return RPC_S_OK;
  1735. }
  1736. inline RPC_STATUS
  1737. OSF_CCALL::InqMarshalledTargetInfo (
  1738. OUT unsigned long *MarshalledTargetInfoLength,
  1739. OUT unsigned char **MarshalledTargetInfo
  1740. )
  1741. {
  1742. if ((Connection->ClientSecurityContext.AuthenticationLevel == RPC_C_AUTHN_LEVEL_NONE)
  1743. || (Connection->ClientSecurityContext.AuthenticationService == RPC_C_AUTHN_NONE))
  1744. return RPC_S_INVALID_BINDING;
  1745. return Connection->ClientSecurityContext.InqMarshalledTargetInfo(MarshalledTargetInfoLength,MarshalledTargetInfo);
  1746. }
  1747. class OSF_BINDING : public MTSyntaxBinding
  1748. {
  1749. public:
  1750. OSF_BINDING (
  1751. IN RPC_SYNTAX_IDENTIFIER *InterfaceId,
  1752. IN TRANSFER_SYNTAX_STUB_INFO *TransferSyntaxInfo,
  1753. IN int CapabilitiesBitmap
  1754. ) : MTSyntaxBinding(InterfaceId, TransferSyntaxInfo, CapabilitiesBitmap),
  1755. RefCount (1)
  1756. {
  1757. }
  1758. inline void SetNextBinding(OSF_BINDING *Next)
  1759. {
  1760. MTSyntaxBinding::SetNextBinding(Next);
  1761. }
  1762. inline OSF_BINDING *GetNextBinding(void)
  1763. {
  1764. return (OSF_BINDING *)(MTSyntaxBinding::GetNextBinding());
  1765. }
  1766. inline int CompareWithTransferSyntax (IN const p_syntax_id_t *TransferSyntax)
  1767. {
  1768. return CompareWithTransferSyntax ((RPC_SYNTAX_IDENTIFIER *)TransferSyntax);
  1769. }
  1770. inline int CompareWithTransferSyntax (IN const RPC_SYNTAX_IDENTIFIER *TransferSyntax)
  1771. {
  1772. return MTSyntaxBinding::CompareWithTransferSyntax ((RPC_SYNTAX_IDENTIFIER *)TransferSyntax);
  1773. }
  1774. // N.B. IsCapabilityBitmapReset is used as flag for the lifetime reference.
  1775. // Whenever we take away the lifetime reference, we reset the capabilities bitmap
  1776. // and we subsequently use IsCapabilityBitmapReset to test whether the lifetime
  1777. // reference has been taken away. This allows us to not add another member to
  1778. // OSF_BINDING and save a data member per object.
  1779. void AddReference (
  1780. void
  1781. )
  1782. {
  1783. int Count;
  1784. // make sure we don't just make up refcounts
  1785. // out of thin air
  1786. ASSERT(RefCount.GetInteger() > 0);
  1787. // make sure the number of refcounts stays reasonable
  1788. ASSERT(RefCount.GetInteger() < 10000);
  1789. Count = RefCount.Increment();
  1790. LogEvent(SU_REFOBJ, EV_INC, this, IntToPtr(0x33), Count, 1, 1);
  1791. }
  1792. void RemoveReference (
  1793. void
  1794. )
  1795. {
  1796. int Count;
  1797. LogEvent(SU_REFOBJ, EV_DEC, this, IntToPtr(0x33), RefCount.GetInteger(), 1, 1);
  1798. Count = RefCount.Decrement();
  1799. ASSERT(Count >= 0);
  1800. if (0 == Count)
  1801. {
  1802. // we just mark the binding as invalid. It will be picked and destroyed
  1803. // next time we iterate the binding list.
  1804. ResetCapabilityBitmap();
  1805. }
  1806. }
  1807. BOOL IsRefCountZero (
  1808. void
  1809. )
  1810. {
  1811. return (RefCount.GetInteger() == 0);
  1812. }
  1813. inline void
  1814. SetPContextVerifiedFlag (
  1815. void
  1816. )
  1817. {
  1818. Flags.SetFlagUnsafe(PContextVerified);
  1819. }
  1820. inline BOOL
  1821. GetPContextVerifiedFlag (
  1822. void
  1823. )
  1824. {
  1825. return Flags.GetFlag(PContextVerified);
  1826. }
  1827. inline void
  1828. ClearPContextVerifiedFlag (
  1829. void
  1830. )
  1831. {
  1832. Flags.ClearFlagUnsafe(PContextVerified);
  1833. }
  1834. private:
  1835. INTERLOCKED_INTEGER RefCount;
  1836. const static unsigned int PContextVerified = 1;
  1837. // can be PContextVerified. As long as it is the only flag, it may be operated
  1838. // unsafely since it only goes from clear to set. If we add new flags, we must
  1839. // switch to interlocks since this is accessed from multiple threads.
  1840. CompositeFlags Flags;
  1841. };
  1842. NEW_SDICT(OSF_BINDING);
  1843. NEW_SDICT(OSF_CCONNECTION);
  1844. enum MPX_TYPES
  1845. {
  1846. mpx_unknown,
  1847. mpx_yes,
  1848. mpx_no
  1849. };
  1850. NEW_SDICT(RPC_TOKEN);
  1851. class OSF_CASSOCIATION : public REFERENCED_OBJECT
  1852. /*++
  1853. Class Description:
  1854. Fields:
  1855. MaintainContext - Contains a flag indicating whether or not this
  1856. association needs to keep at least one connection open with
  1857. the server if at all possible. A non-zero value indicates that
  1858. at least one connection should be kept open.
  1859. CallIdCounter - Contains an interlocked integer used to allocate
  1860. unique call identifiers.
  1861. BindHandleCount - Counts the number of OSF_BINDING_HANDLEs using
  1862. this association. This particular variable is operated
  1863. with interlocks. However, adding a refcount if you don't have
  1864. one (as in FindOrCreateAssociation - through the global data
  1865. structure) requires holding AssocDictMutex.
  1866. --*/
  1867. {
  1868. friend class OSF_CCONNECTION;
  1869. friend class OSF_CCALL;
  1870. friend class OSF_BINDING_HANDLE;
  1871. friend class OSF_CCALL_AVRF;
  1872. private:
  1873. DCE_BINDING * DceBinding;
  1874. INTERLOCKED_INTEGER BindHandleCount;
  1875. ULONG AssocGroupId;
  1876. OSF_BINDING_DICT Bindings;
  1877. OSF_CCONNECTION_DICT ActiveConnections;
  1878. TRANS_INFO *TransInfo ;
  1879. unsigned char * SecondaryEndpoint;
  1880. int Key;
  1881. UINT OpenConnectionCount;
  1882. UINT ConnectionsDoingBindCount;
  1883. BOOL fPossibleServerReset;
  1884. UINT MaintainContext;
  1885. ULONG CallIdCounter;
  1886. MUTEX AssociationMutex;
  1887. BOOL AssociationValid;
  1888. // in some cases we will decide that the association is dead,
  1889. // and we will mark it as such so that other calls can
  1890. // quickly fail instead of banging against a dead server.
  1891. // The error with which the association was shutdown is
  1892. // stored here. Callers that implement quick failure detection
  1893. // can read it off here. This is valid only if
  1894. // AssociationValid == FALSE.
  1895. RPC_STATUS AssociationShutdownError;
  1896. BOOL DontLinger;
  1897. BOOL ResolverHintInitialized;
  1898. // protected by the AssociationMutex
  1899. BOOL fIdleConnectionCleanupNeeded;
  1900. int FailureCount;
  1901. MPX_TYPES fMultiplex;
  1902. unsigned long SavedDrep;
  1903. RPC_TOKEN_DICT TokenDict;
  1904. union
  1905. {
  1906. struct
  1907. {
  1908. // TRUE if this is an association without binding handle
  1909. // references to it (i.e. it is lingered), FALSE
  1910. // otherwise. Protected by the AssocDictMutex
  1911. BOOL fAssociationLingered;
  1912. // The timestamp for garbage collecting this item. Defined
  1913. // only if fAssociationLingered == TRUE. Protected by the
  1914. // AssocDictMutex
  1915. DWORD Timestamp;
  1916. } Linger;
  1917. // this arm of the union is used only during destruction - never use
  1918. // it outside
  1919. OSF_CASSOCIATION *NextAssociation;
  1920. };
  1921. // if non-zero, it means that the resolved endpoint to the server was
  1922. // mutually authenticated using the endpoint mapper. Zero otherwise.
  1923. // Protected by the AssocDictMutex.
  1924. BOOL LocalMASet;
  1925. public:
  1926. OSF_CASSOCIATION (
  1927. IN DCE_BINDING * DceBinding,
  1928. IN TRANS_INFO *TransInfo,
  1929. IN OUT RPC_STATUS * RpcStatus
  1930. );
  1931. ~OSF_CASSOCIATION (
  1932. );
  1933. public:
  1934. #if 0
  1935. void
  1936. CleanupAuthenticatedConnections(
  1937. IN CLIENT_AUTH_INFO *ClientAuthInfo
  1938. );
  1939. #endif
  1940. void
  1941. UnBind ( // Decrement the BindingCount, and clean up the
  1942. // association if it reaches zero.
  1943. );
  1944. RPC_STATUS
  1945. FindOrCreateOsfBinding (
  1946. IN PRPC_CLIENT_INTERFACE RpcInterfaceInformation,
  1947. IN RPC_MESSAGE *Message,
  1948. OUT int *NumberOfBindings,
  1949. IN OUT OSF_BINDING *BindingsForThisInterface[]
  1950. );
  1951. BOOL
  1952. DoesBindingForInterfaceExist (
  1953. IN PRPC_CLIENT_INTERFACE RpcInterfaceInformation
  1954. );
  1955. RPC_STATUS
  1956. AllocateCCall (
  1957. IN OSF_BINDING_HANDLE *BindingHandle,
  1958. IN PRPC_MESSAGE Message,
  1959. IN CLIENT_AUTH_INFO * ClientAuthInfo,
  1960. OUT OSF_CCALL ** CCall,
  1961. OUT BOOL *fBindingHandleReferenceRemoved
  1962. );
  1963. private:
  1964. RPC_STATUS
  1965. ProcessBindAckOrNak (
  1966. IN rpcconn_common *Buffer,
  1967. IN UINT BufferLength,
  1968. IN OSF_CCONNECTION *CConnection,
  1969. IN OSF_CCALL *CCall,
  1970. OUT ULONG *NewGroupId,
  1971. OUT OSF_BINDING **BindingNegotiated,
  1972. OUT FAILURE_COUNT_STATE *fFailureCountExceeded OPTIONAL
  1973. );
  1974. RPC_STATUS
  1975. LookForExistingConnection (
  1976. IN OSF_BINDING_HANDLE *BindingHandle,
  1977. IN BOOL fExclusive,
  1978. IN CLIENT_AUTH_INFO *ClientAuthInfo,
  1979. IN int *PresentContext,
  1980. IN int NumberOfPresentationContexts,
  1981. OUT OSF_CCONNECTION **NewConnection,
  1982. OUT int *PresentationContextSupported,
  1983. OUT OSF_CCALL_STATE *InitialCallState,
  1984. IN BOOL fNonCausal
  1985. );
  1986. inline void
  1987. ClearIdleConnectionCleanupFlag (
  1988. void
  1989. )
  1990. {
  1991. AssociationMutex.VerifyOwned();
  1992. if (fIdleConnectionCleanupNeeded)
  1993. {
  1994. fIdleConnectionCleanupNeeded = FALSE;
  1995. if (InterlockedDecrement(&PeriodicGarbageCollectItems) == 0)
  1996. {
  1997. #if defined (RPC_GC_AUDIT)
  1998. DbgPrintEx(77, DPFLTR_WARNING_LEVEL, "%d (0x%X) PeriodicGarbageCollectItems dropped to 0 (a)\n",
  1999. GetCurrentProcessId(), GetCurrentProcessId());
  2000. #endif
  2001. }
  2002. }
  2003. }
  2004. public:
  2005. int
  2006. CompareWithDceBinding (
  2007. IN DCE_BINDING * DceBinding,
  2008. OUT BOOL *fOnlyEndpointDifferent
  2009. );
  2010. //
  2011. // Note, whoever calls this routine must have already
  2012. // requested the AssociationDictMutex.
  2013. //
  2014. void
  2015. IncrementCount (
  2016. void
  2017. )
  2018. {
  2019. LogEvent(SU_CASSOC, EV_INC, this, (PVOID)2, BindHandleCount.GetInteger(), 1, 0);
  2020. BindHandleCount.Increment();
  2021. }
  2022. void
  2023. ShutdownRequested (
  2024. IN RPC_STATUS AssociationShutdownError OPTIONAL,
  2025. IN OSF_CCONNECTION *ExemptConnection OPTIONAL
  2026. );
  2027. inline OSF_BINDING *
  2028. FindBinding (
  2029. IN int PresentContext
  2030. )
  2031. {
  2032. return(Bindings.Find(PresentContext));
  2033. }
  2034. void FreeAllBindings (
  2035. void
  2036. );
  2037. void DestroyBinding (
  2038. IN OSF_BINDING *Binding
  2039. );
  2040. virtual RPC_STATUS
  2041. ToStringBinding (
  2042. OUT RPC_CHAR * * StringBinding,
  2043. IN RPC_UUID * ObjectUuid
  2044. );
  2045. OSF_CCONNECTION *
  2046. FindIdleConnection (
  2047. void
  2048. );
  2049. void
  2050. MaintainingContext (
  2051. );
  2052. DCE_BINDING *
  2053. DuplicateDceBinding (
  2054. );
  2055. BOOL
  2056. IsValid (
  2057. );
  2058. BOOL
  2059. ConnectionAborted (
  2060. IN OSF_CCONNECTION *Connection
  2061. );
  2062. void
  2063. NotifyConnectionOpen (
  2064. );
  2065. void
  2066. NotifyConnectionClosed (
  2067. );
  2068. void NotifyConnectionBindInProgress (
  2069. void
  2070. );
  2071. void NotifyConnectionBindCompleted (
  2072. void
  2073. );
  2074. void * operator new (
  2075. size_t allocBlock,
  2076. unsigned int xtraBytes
  2077. );
  2078. int
  2079. CompareResolverHint (
  2080. void *Hint
  2081. );
  2082. void *
  2083. InqResolverHint (
  2084. );
  2085. void
  2086. SetResolverHint (
  2087. void *Hint
  2088. );
  2089. void
  2090. FreeResolverHint (
  2091. void *Hint
  2092. );
  2093. inline BOOL
  2094. IsResolverHintSynchronizationNeeded (
  2095. void
  2096. );
  2097. inline void
  2098. ResetAssociation (
  2099. )
  2100. {
  2101. AssociationMutex.VerifyOwned();
  2102. AssocGroupId = 0;
  2103. LocalMASet = FALSE;
  2104. if (ResolverHintInitialized)
  2105. {
  2106. ResolverHintInitialized = FALSE;
  2107. FreeResolverHint(InqResolverHint());
  2108. }
  2109. }
  2110. BOOL
  2111. IsAssociationReset ( void )
  2112. {
  2113. return (AssocGroupId == 0);
  2114. }
  2115. RPC_STATUS
  2116. FindOrCreateToken (
  2117. IN HANDLE hToken,
  2118. IN LUID *pLuid,
  2119. OUT RPC_TOKEN **ppToken,
  2120. OUT BOOL *pfTokenFound
  2121. );
  2122. void
  2123. ReferenceToken(
  2124. IN RPC_TOKEN *pToken
  2125. );
  2126. void
  2127. DereferenceToken(
  2128. IN RPC_TOKEN *pToken
  2129. );
  2130. void
  2131. CleanupConnectionList(
  2132. IN RPC_TOKEN *pToken
  2133. );
  2134. static void
  2135. OsfDeleteLingeringAssociations (
  2136. void
  2137. );
  2138. inline BOOL
  2139. GetDontLingerState (
  2140. void
  2141. )
  2142. {
  2143. return DontLinger;
  2144. }
  2145. inline void
  2146. SetDontLingerState (
  2147. IN BOOL DontLinger
  2148. )
  2149. {
  2150. ASSERT(DontLinger == TRUE);
  2151. this->DontLinger = DontLinger;
  2152. }
  2153. };
  2154. inline int
  2155. OSF_CASSOCIATION::CompareResolverHint (
  2156. void *Hint
  2157. )
  2158. {
  2159. RPC_CONNECTION_TRANSPORT *ClientInfo =
  2160. (RPC_CONNECTION_TRANSPORT *) TransInfo->InqTransInfo();
  2161. if (ClientInfo->CompareResolverHint)
  2162. {
  2163. return ClientInfo->CompareResolverHint(TransResolverHint(), Hint);
  2164. }
  2165. else
  2166. {
  2167. return RpcpMemoryCompare(TransResolverHint(), Hint, ClientInfo->ResolverHintSize);
  2168. }
  2169. }
  2170. inline void *
  2171. OSF_CASSOCIATION::InqResolverHint (
  2172. )
  2173. {
  2174. return TransResolverHint();
  2175. }
  2176. inline void
  2177. OSF_CASSOCIATION::SetResolverHint (
  2178. void *Hint
  2179. )
  2180. {
  2181. RPC_CONNECTION_TRANSPORT *ClientInfo =
  2182. (RPC_CONNECTION_TRANSPORT *) TransInfo->InqTransInfo();
  2183. if (ClientInfo->CopyResolverHint)
  2184. {
  2185. if (TransResolverHint() != Hint)
  2186. {
  2187. ClientInfo->CopyResolverHint(TransResolverHint(),
  2188. Hint,
  2189. TRUE // SourceWillBeAbandoned
  2190. );
  2191. }
  2192. }
  2193. else
  2194. {
  2195. RpcpMemoryCopy(TransResolverHint(), Hint, ClientInfo->ResolverHintSize);
  2196. }
  2197. }
  2198. inline void
  2199. OSF_CASSOCIATION::FreeResolverHint (
  2200. void *Hint
  2201. )
  2202. {
  2203. RPC_CONNECTION_TRANSPORT *ClientInfo =
  2204. (RPC_CONNECTION_TRANSPORT *) TransInfo->InqTransInfo();
  2205. if (ClientInfo->FreeResolverHint)
  2206. {
  2207. ClientInfo->FreeResolverHint(Hint);
  2208. }
  2209. }
  2210. BOOL
  2211. OSF_CASSOCIATION::IsResolverHintSynchronizationNeeded (
  2212. void
  2213. )
  2214. {
  2215. RPC_CONNECTION_TRANSPORT *ClientInfo =
  2216. (RPC_CONNECTION_TRANSPORT *) TransInfo->InqTransInfo();
  2217. return (ClientInfo->FreeResolverHint != NULL);
  2218. }
  2219. inline void *
  2220. OSF_CASSOCIATION::operator new (
  2221. size_t allocBlock,
  2222. unsigned int xtraBytes
  2223. )
  2224. {
  2225. I_RPC_HANDLE pvTemp = (I_RPC_HANDLE) new char[allocBlock + xtraBytes];
  2226. return(pvTemp);
  2227. }
  2228. inline BOOL
  2229. OSF_CASSOCIATION::IsValid (
  2230. )
  2231. {
  2232. return AssociationValid ;
  2233. }
  2234. inline void
  2235. OSF_CASSOCIATION::MaintainingContext (
  2236. )
  2237. /*++
  2238. Routine Description:
  2239. This routine is used to indicate that a binding handle using this
  2240. association is maintaining context with the server. This means
  2241. that at least one connection for this association must always be
  2242. open.
  2243. --*/
  2244. {
  2245. MaintainContext = 1;
  2246. }
  2247. inline DCE_BINDING *
  2248. OSF_CASSOCIATION::DuplicateDceBinding (
  2249. )
  2250. {
  2251. return(DceBinding->DuplicateDceBinding());
  2252. }
  2253. inline ULONG
  2254. OSF_CCONNECTION::GetAssocGroupId (
  2255. )
  2256. {
  2257. return Association->AssocGroupId ;
  2258. }
  2259. inline void
  2260. OSF_CCONNECTION::WaitForSend (
  2261. )
  2262. {
  2263. while (ConnectionReady == 0)
  2264. {
  2265. //
  2266. // We need a listening thread
  2267. // so the send can complete
  2268. //
  2269. Association->TransInfo->CreateThread();
  2270. Sleep(10);
  2271. }
  2272. ASSERT(ConnectionReady == 1);
  2273. ConnectionReady = 0;
  2274. }
  2275. inline void
  2276. OSF_CCONNECTION::DeleteConnection (
  2277. )
  2278. {
  2279. if (fExclusive == 0)
  2280. {
  2281. TransAbortConnection();
  2282. }
  2283. Delete();
  2284. }
  2285. inline RPC_CHAR *OSF_CCONNECTION::InqEndpoint(void)
  2286. {
  2287. return Association->DceBinding->InqEndpoint();
  2288. }
  2289. inline RPC_CHAR *OSF_CCONNECTION::InqNetworkAddress(void)
  2290. {
  2291. return Association->DceBinding->InqNetworkAddress();
  2292. }
  2293. inline int
  2294. OSF_CCONNECTION::AddPContext (
  2295. IN int PresentContext
  2296. )
  2297. {
  2298. Association->AssociationMutex.VerifyOwned();
  2299. return(Bindings.Insert(PresentContext));
  2300. }
  2301. inline void
  2302. OSF_CCONNECTION::DeletePContext (
  2303. IN int PresentContext
  2304. )
  2305. {
  2306. Association->AssociationMutex.VerifyOwned();
  2307. Bindings.Delete(PresentContext);
  2308. }
  2309. inline int
  2310. OSF_CCONNECTION::SupportedPContext (
  2311. IN int *PresentationContexts,
  2312. IN int NumberOfPresentationContexts,
  2313. OUT int *PresentationContextSupported
  2314. )
  2315. /*++
  2316. Return Value:
  2317. Non-zero will be returned if this connection supports the supplied
  2318. presentation context; otherwise, zero will be returned.
  2319. --*/
  2320. {
  2321. int i;
  2322. int Result = 0;
  2323. Association->AssociationMutex.VerifyOwned();
  2324. ASSERT(NumberOfPresentationContexts);
  2325. for (i = 0; i < NumberOfPresentationContexts; i ++)
  2326. {
  2327. Result = Bindings.MemberP(PresentationContexts[i]);
  2328. if (Result)
  2329. {
  2330. *PresentationContextSupported = i;
  2331. break;
  2332. }
  2333. }
  2334. return Result;
  2335. }
  2336. inline void
  2337. OSF_BINDING_HANDLE::Unbind ()
  2338. {
  2339. BOOL fMutexTaken;
  2340. // try to take the two mutexes, but if fail on the second, release
  2341. // the first as well and retry, because there is a potential
  2342. // deadlock condition for which this is a workaround
  2343. while (TRUE)
  2344. {
  2345. AssocDictMutex->Request();
  2346. fMutexTaken = Association->AssociationMutex.TryRequest();
  2347. if (fMutexTaken)
  2348. break;
  2349. else
  2350. {
  2351. AssocDictMutex->Clear();
  2352. Sleep(10);
  2353. }
  2354. }
  2355. if (pToken)
  2356. {
  2357. Association->DereferenceToken(pToken);
  2358. pToken = 0;
  2359. }
  2360. // unbind will clear the association dict mutex
  2361. // and the association mutex.
  2362. // If the association is not lingered, it may be freed.
  2363. // We can't touch Association after this point.
  2364. Association->UnBind();
  2365. Association = 0;
  2366. }
  2367. RPC_STATUS
  2368. LoadableTransportClientInfo (
  2369. IN RPC_CHAR * DllName,
  2370. IN RPC_CHAR * RpcProtocolSequence,
  2371. OUT TRANS_INFO * *ClientTransInfo
  2372. );
  2373. TRANS_INFO *
  2374. GetLoadedClientTransportInfoFromId (
  2375. IN unsigned short TransportId
  2376. );
  2377. void ReleaseBindingListWithException (
  2378. IN OSF_BINDING *ExemptBinding, OPTIONAL
  2379. IN OSF_BINDING *BindingList
  2380. );
  2381. inline void ReleaseBindingList (
  2382. IN OSF_BINDING *BindingList
  2383. )
  2384. /*++
  2385. Routine Description:
  2386. Removes a refcount on all bindings in the list.
  2387. Arguments:
  2388. BindingList - the list of bindings.
  2389. Return Value:
  2390. --*/
  2391. {
  2392. return ReleaseBindingListWithException(NULL, // ExemptBinding
  2393. BindingList
  2394. );
  2395. }
  2396. RPC_STATUS SetAuthInformation (
  2397. IN RPC_BINDING_HANDLE BindingHandle,
  2398. IN CLIENT_AUTH_INFO *AuthInfo
  2399. );
  2400. // --------------------------------------------------------------------
  2401. #endif // __OSFCLNT_HXX__