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.

1884 lines
45 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1990 - 1999
  6. //
  7. // File: osfsvr.hxx
  8. //
  9. //--------------------------------------------------------------------------
  10. /* --------------------------------------------------------------------
  11. File : osfsvr.hxx
  12. Title : Classes for the OSF RPC protocol module (server classes).
  13. Description :
  14. History :
  15. mikemon ??-??-?? Beginning of recorded history.
  16. mikemon 10-15-90 Changed the shutdown functionality to PauseExecution
  17. rather than suspending and resuming a thread.
  18. mikemon 10-16-90 Added ListenThreadCompleted to OSF_ADDRESS.
  19. Kamen Moutafov (kamenm) Jan-2000 Support for multiple transfer syntaxes
  20. Kamen Moutafov (KamenM) Dec 99 - Feb 2000 - Support for cell debugging stuff
  21. -------------------------------------------------------------------- */
  22. #ifndef __OSFSVR_HXX__
  23. #define __OSFSVR_HXX__
  24. enum OSF_SCALL_STATE
  25. {
  26. NewRequest,
  27. CallCancelled,
  28. CallAborted,
  29. CallCompleted,
  30. ReceivedCallback,
  31. ReceivedCallbackReply,
  32. ReceivedFault
  33. };
  34. class OSF_SCONNECTION;
  35. class OSF_SCALL;
  36. NEW_SDICT(OSF_ASSOCIATION);
  37. #define InqTransAddress(RpcTransportAddress) \
  38. ((OSF_ADDRESS *) \
  39. ((char *) RpcTransportAddress - sizeof(OSF_ADDRESS)))
  40. #define InqTransSConnection(RpcTransportConnection) \
  41. ((OSF_SCONNECTION *) \
  42. ((char *) RpcTransportConnection - sizeof(OSF_SCONNECTION)))
  43. #define InqTransSCall(RpcSourceContext) \
  44. ((OSF_SCALL *) ((char *) RpcSourceContext - sizeof(OSF_SCALL)))
  45. NEW_SDICT(OSF_SCONNECTION);
  46. const int NumberOfAssociationsDictionaries = 8;
  47. const int MutexAllocationSize = ( ((unsigned long)(sizeof(MUTEX)) + ((4)-1)) & ~(4 - 1) );
  48. class OSF_ADDRESS : public RPC_ADDRESS
  49. /*++
  50. Class Description:
  51. Fields:
  52. SetupAddressOccurred - Contains a flag which indicates whether or
  53. not SetupAddressWithEndpoint or SetupAddressUnknownEndpoint
  54. have been called and returned success. A value of non-zero
  55. indicates that the above (SetupAddress* has been called and
  56. succeeded) occured.
  57. ServerInfo - Contains the pointers to the loadable transport
  58. routines for the transport type of this address.
  59. --*/
  60. {
  61. private:
  62. OSF_ASSOCIATION_DICT Associations[NumberOfAssociationsDictionaries];
  63. unsigned char AssociationBucketMutexMemory[MutexAllocationSize * NumberOfAssociationsDictionaries];
  64. RPC_CONNECTION_TRANSPORT * ServerInfo;
  65. unsigned int SetupAddressOccurred;
  66. int ServerListeningFlag;
  67. DebugEndpointInfo *DebugCell;
  68. CellTag DebugCellTag;
  69. public:
  70. OSF_ADDRESS (
  71. IN TRANS_INFO * RpcTransInfoInfo,
  72. IN OUT RPC_STATUS * RpcStatus
  73. );
  74. ~OSF_ADDRESS (
  75. );
  76. virtual RPC_STATUS
  77. ServerStartingToListen (
  78. IN unsigned int MinimumCallThreads,
  79. IN unsigned int MaximumConcurrentCalls
  80. );
  81. virtual RPC_STATUS
  82. ServerSetupAddress (
  83. IN RPC_CHAR * NetworkAddress,
  84. IN RPC_CHAR * *Endpoint,
  85. IN unsigned int PendingQueueSize,
  86. IN void * SecurityDescriptor, OPTIONAL
  87. IN unsigned long EndpointFlags,
  88. IN unsigned long NICFlags
  89. );
  90. #ifndef NO_PLUG_AND_PLAY
  91. virtual void
  92. PnpNotify (
  93. );
  94. #endif
  95. OSF_SCONNECTION *
  96. NewConnection (
  97. );
  98. RPC_TRANSPORT_ADDRESS
  99. InqRpcTransportAddress (
  100. );
  101. RPC_STATUS
  102. CompleteListen (
  103. );
  104. RPC_STATUS
  105. CreateThread (
  106. );
  107. virtual unsigned int // Returns the length of the secondary address.
  108. TransSecondarySize ( // The length will be used to allocate a buffer.
  109. );
  110. virtual RPC_STATUS
  111. TransSecondary ( // Places the secondary address in the specified buffer.
  112. IN unsigned char * Address, // Buffer for the address.
  113. IN unsigned int AddressLength // Length of the buffer.
  114. );
  115. void
  116. ServerStoppedListening (
  117. );
  118. OSF_ASSOCIATION * // Returns the association deleted or 0.
  119. RemoveAssociation ( // Remove the association specified by Key from this
  120. // address.
  121. IN int Key,
  122. IN OSF_ASSOCIATION *pAssociation
  123. );
  124. int // Indicates success (0), or an error (-1).
  125. AddAssociation ( // Add the specified association to this address.
  126. IN OSF_ASSOCIATION * TheAssociation
  127. );
  128. OSF_ASSOCIATION *
  129. FindAssociation (
  130. IN unsigned long AssociationGroupId,
  131. IN RPC_CLIENT_PROCESS_IDENTIFIER * ClientProcess
  132. );
  133. int
  134. IsServerListening (
  135. ) ;
  136. void *
  137. operator new (
  138. size_t allocBlock,
  139. unsigned int xtraBytes
  140. );
  141. inline static int GetHashBucketForAssociation(IN unsigned long AssociationGroupId)
  142. {
  143. return (AssociationGroupId % NumberOfAssociationsDictionaries);
  144. }
  145. inline MUTEX *GetAssociationBucketMutex(IN int HashIndex)
  146. {
  147. MUTEX *pMutex;
  148. pMutex = (MUTEX *)(&AssociationBucketMutexMemory[MutexAllocationSize * HashIndex]);
  149. ASSERT((((ULONG_PTR)pMutex) % 4) == 0);
  150. return pMutex;
  151. }
  152. inline void GetDebugCellIDForThisObject(OUT DebugCellID *CellID)
  153. {
  154. GetDebugCellIDFromDebugCell((DebugCellUnion *)DebugCell, &DebugCellTag, CellID);
  155. }
  156. virtual void
  157. DestroyContextHandlesForInterface (
  158. IN RPC_SERVER_INTERFACE PAPI * RpcInterfaceInformation,
  159. IN BOOL RundownContextHandles
  160. );
  161. NETWORK_ADDRESS_VECTOR *
  162. GetNetworkAddressVector (
  163. void
  164. )
  165. {
  166. return ServerInfo->GetNetworkAddressVector(InqRpcTransportAddress());
  167. }
  168. };
  169. inline RPC_STATUS
  170. OSF_ADDRESS::CreateThread (
  171. )
  172. {
  173. return TransInfo->CreateThread();
  174. }
  175. inline RPC_TRANSPORT_ADDRESS
  176. OSF_ADDRESS::InqRpcTransportAddress (
  177. )
  178. /*++
  179. Return Value:
  180. A pointer to the transport data for this address will be returned.
  181. --*/
  182. {
  183. return((RPC_TRANSPORT_ADDRESS)
  184. (((char *) this) + sizeof(OSF_ADDRESS)));
  185. }
  186. inline void *
  187. OSF_ADDRESS::operator new (
  188. size_t allocBlock,
  189. unsigned int xtraBytes
  190. )
  191. {
  192. void * pvTemp = RpcpFarAllocate(allocBlock + xtraBytes);
  193. return(pvTemp);
  194. }
  195. inline int
  196. OSF_ADDRESS::IsServerListening (
  197. )
  198. {
  199. return ServerListeningFlag ;
  200. }
  201. #define RPCSTATUS_GET_CREATETHREAD(x) Server->CreateThread( \
  202. (THREAD_PROC)&ReceiveLotsaCallsWrapper,x);
  203. class OSF_SBINDING
  204. {
  205. private:
  206. RPC_INTERFACE * Interface;
  207. unsigned int PresentContext;
  208. unsigned long CurrentSecId;
  209. int SelectedTransferSyntaxIndex; // zero based
  210. public:
  211. unsigned long SequenceNumber ;
  212. OSF_SBINDING ( // Constructor.
  213. IN RPC_INTERFACE * TheInterface,
  214. IN int PContext,
  215. IN int SelectedTransferSyntaxIndex
  216. );
  217. RPC_INTERFACE *
  218. GetInterface (
  219. ) {return(Interface);}
  220. unsigned int
  221. GetPresentationContext (
  222. ) {return(PresentContext);}
  223. inline RPC_STATUS
  224. CheckSecurity (
  225. SCALL * Call,
  226. unsigned long AuthId
  227. );
  228. void GetSelectedTransferSyntaxAndDispatchTable(
  229. OUT RPC_SYNTAX_IDENTIFIER **SelectedTransferSyntax,
  230. OUT PRPC_DISPATCH_TABLE *SelectedDispatchTable)
  231. {
  232. Interface->GetSelectedTransferSyntaxAndDispatchTable(SelectedTransferSyntaxIndex,
  233. SelectedTransferSyntax, SelectedDispatchTable);
  234. }
  235. inline RPC_SYNTAX_IDENTIFIER *GetInterfaceId (
  236. void
  237. )
  238. {
  239. return &(Interface->InqInterfaceInformation()->InterfaceId);
  240. }
  241. inline RPC_SYNTAX_IDENTIFIER *GetTransferSyntaxId (
  242. void
  243. )
  244. {
  245. RPC_DISPATCH_TABLE *Ignored;
  246. RPC_SYNTAX_IDENTIFIER *TransferSyntaxId;
  247. Interface->GetSelectedTransferSyntaxAndDispatchTable(SelectedTransferSyntaxIndex,
  248. &TransferSyntaxId, &Ignored);
  249. return TransferSyntaxId;
  250. }
  251. #if DBG
  252. inline void
  253. InterfaceForCallDoesNotUseStrict (
  254. void
  255. )
  256. {
  257. Interface->InterfaceDoesNotUseStrict();
  258. }
  259. #endif
  260. };
  261. class OSF_SCONNECTION;
  262. NEW_SDICT(OSF_SBINDING);
  263. NEW_SDICT(SECURITY_CONTEXT);
  264. class OSF_SCALL : public SCALL
  265. /*++
  266. Class Description:
  267. Fields:
  268. ObjectUuid - Contains the object UUID specified for the remote
  269. procedure call by the client.
  270. ObjectUuidSpecified - Contains a flag which indicates whether
  271. or not the remote procedure call specified an object UUID.
  272. This field will be zero if an object UUID was not specified
  273. in the call, and non-zero if one was specified.
  274. ServerSecurityContext - Contains the security context for this connection
  275. if security is being performed at the rpc protocol level.
  276. AuthenticationLevel - Contains a value indicating what authentication
  277. is being performed at the rpc protocol level. A value of
  278. RPC_C_AUTHN_LEVEL_NONE indicates that no authentication is being
  279. performed at the rpc protocol level.
  280. AuthenticationService - Contains which authentication service is being
  281. used at the rpc protocol level.
  282. AuthorizationService - Contains which authorization service is being
  283. used at the rpc protocol level.
  284. AdditionalSpaceForSecurity - Contains the amount of space to save for
  285. security in each buffer we allocate.
  286. CachedBuffer - Contains cached buffer.
  287. CachedBufferLength - Contains the length of the cached buffer.
  288. DceSecurityInfo - Contains the security information necessary for
  289. DCE security to work correctly.
  290. SavedPac - While a call is being dispatched to manager, the manager
  291. could query for a PAC. However, manager is not explicitly going
  292. to free the PAC. Runtime is supposed to do that. This feild
  293. takes care of that.
  294. AuthzSvc - Authorization service
  295. --*/
  296. {
  297. friend OSF_SCONNECTION;
  298. private:
  299. // data member ordering is optimized for locality
  300. // If you modify something, make sure that the section boundaries are
  301. // preserved. It is assumed that in the common case the OSF_SCALL is used
  302. // by a thread at a time. Ordering is by frequency of usage, regardless of
  303. // read/write
  304. // Most frequently used section ( >= 3 times per call):
  305. OSF_SCONNECTION *Connection;
  306. OSF_SBINDING * CurrentBinding;
  307. void *CurrentBuffer;
  308. unsigned int CurrentBufferLength ;
  309. int CurrentOffset;
  310. ULONG MaxSecuritySize;
  311. // the info for the first call. This has to be on the
  312. // heap, because it is used on the async paths
  313. // recursive callback info is on the stack, because we
  314. // know in recursive callback we're only sync
  315. RPC_MESSAGE FirstCallRpcMessage;
  316. RPC_RUNTIME_INFO FirstCallRuntimeInfo;
  317. // ~2 times per call use
  318. OSF_ADDRESS *Address;
  319. unsigned long CallId;
  320. int CallStack;
  321. void *LastBuffer;
  322. int DispatchBufferOffset;
  323. ULONG MaximumFragmentLength;
  324. MUTEX CallMutex;
  325. BOOL FirstSend;
  326. // ~1 time per call use
  327. unsigned int ObjectUuidSpecified;
  328. BOOL fCallDispatched;
  329. int ProcNum;
  330. OSF_SCALL_STATE CurrentState;
  331. BOOL fSecurityFailure;
  332. THREAD * Thread;
  333. int DispatchFlags;
  334. CellTag CellTag;
  335. DebugCallInfo *DebugCell;
  336. // not used or used few times
  337. int FirstFrag ;
  338. BOOL fPipeCall;
  339. int AllocHint;
  340. ULONG RcvBufferLength;
  341. ULONG NeededLength;
  342. ULONG ActualBufferLength;
  343. QUEUE BufferQueue;
  344. BOOL fChoked;
  345. BOOL fPeerChoked;
  346. int CallOrphaned;
  347. unsigned long SavedHeaderSize;
  348. void * SavedHeader;
  349. EVENT SyncEvent;
  350. void *SendContext;
  351. RPC_UUID ObjectUuid;
  352. BOOL fAsyncPipeCall;
  353. // This is a captured value of the flag RPC_C_NOTIFY_ON_SEND_COMPLETE
  354. // from pAsync->Flags. We need to capture it since when async pipes are
  355. // used with no notification pAsync may be gone while a send-complete
  356. // response is being processed, but we will need to read this flag.
  357. BOOL fNotifyOnSendComplete;
  358. void
  359. UpdateBuffersAfterNonLastSend (
  360. IN PVOID NewBuffer,
  361. IN int RemainingLength,
  362. IN OUT RPC_MESSAGE *Message
  363. )
  364. {
  365. if (RemainingLength)
  366. {
  367. Message->Buffer = NewBuffer;
  368. Message->BufferLength = RemainingLength;
  369. ActualBufferLength = RemainingLength;
  370. }
  371. else
  372. {
  373. Message->Buffer = 0;
  374. Message->BufferLength = 0;
  375. ActualBufferLength = 0;
  376. }
  377. }
  378. public:
  379. LONG CancelPending;
  380. OSF_SCALL (
  381. IN OSF_SCONNECTION *Connection,
  382. IN OUT RPC_STATUS *Status
  383. );
  384. virtual ~OSF_SCALL (
  385. );
  386. virtual RPC_STATUS
  387. SendReceive (
  388. IN OUT PRPC_MESSAGE Message
  389. );
  390. virtual RPC_STATUS
  391. NegotiateTransferSyntax (
  392. IN OUT PRPC_MESSAGE Message
  393. );
  394. virtual RPC_STATUS
  395. GetBuffer (
  396. IN OUT PRPC_MESSAGE Message,
  397. IN UUID *ObjectUuid
  398. );
  399. RPC_STATUS
  400. GetBufferDo (
  401. IN OUT void ** ppBuffer,
  402. IN unsigned int culRequiredLength,
  403. IN BOOL fDataValid = 0,
  404. IN unsigned int DataLength = 0,
  405. IN unsigned long Extra = 0
  406. );
  407. void
  408. FreeBufferDo (
  409. IN void *pBuffer
  410. );
  411. virtual void
  412. FreeBuffer (
  413. IN PRPC_MESSAGE Message
  414. );
  415. virtual void
  416. FreePipeBuffer (
  417. IN PRPC_MESSAGE Message
  418. ) ;
  419. virtual RPC_STATUS
  420. ReallocPipeBuffer (
  421. IN PRPC_MESSAGE Message,
  422. IN unsigned int NewSize
  423. ) ;
  424. virtual RPC_STATUS
  425. Receive (
  426. IN OUT PRPC_MESSAGE Message,
  427. IN unsigned int Size
  428. ) ;
  429. virtual RPC_STATUS
  430. AsyncSend (
  431. IN OUT PRPC_MESSAGE Message
  432. ) ;
  433. virtual RPC_STATUS
  434. AsyncReceive (
  435. IN OUT PRPC_MESSAGE Message,
  436. IN unsigned int Size
  437. ) ;
  438. virtual RPC_STATUS
  439. SetAsyncHandle (
  440. IN PRPC_ASYNC_STATE pAsync
  441. ) ;
  442. virtual RPC_STATUS
  443. AbortAsyncCall (
  444. IN PRPC_ASYNC_STATE pAsync,
  445. IN unsigned long ExceptionCode
  446. ) ;
  447. void
  448. SendFault (
  449. IN RPC_STATUS Status,
  450. IN int DidNotExecute
  451. );
  452. RPC_STATUS
  453. TransGetBuffer ( // Allocate a buffer of the specified size.
  454. OUT void * * Buffer,
  455. IN unsigned int BufferLength
  456. );
  457. virtual void
  458. TransFreeBuffer ( // Free a buffer.
  459. IN void * Buffer
  460. );
  461. virtual BOOL
  462. IsSyncCall (
  463. );
  464. virtual RPC_STATUS
  465. InquireAuthClient (
  466. OUT RPC_AUTHZ_HANDLE * Privileges,
  467. OUT RPC_CHAR * * ServerPrincipalName, OPTIONAL
  468. OUT unsigned long * AuthenticationLevel,
  469. OUT unsigned long * AuthenticationService,
  470. OUT unsigned long * AuthorizationService,
  471. IN unsigned long Flags
  472. );
  473. virtual RPC_STATUS
  474. InquireCallAttributes (
  475. IN OUT void *RpcCallAttributes
  476. );
  477. virtual void
  478. ProcessSendComplete (
  479. IN RPC_STATUS EventStatus,
  480. IN BUFFER Buffer
  481. );
  482. BOOL
  483. BeginRpcCall (
  484. IN rpcconn_common * Packet,
  485. IN unsigned int PacketLength
  486. );
  487. BOOL
  488. ProcessReceivedPDU (
  489. IN rpcconn_common * Packet,
  490. IN unsigned int PacketLength,
  491. IN BOOL fDispatch = 0
  492. );
  493. RPC_STATUS
  494. GetCoalescedBuffer (
  495. IN PRPC_MESSAGE Message,
  496. BOOL fForceExtra
  497. );
  498. BOOL
  499. DispatchRPCCall (
  500. IN unsigned char PTYPE,
  501. IN unsigned short OpNum
  502. );
  503. void
  504. DispatchHelper (
  505. );
  506. RPC_STATUS
  507. Send(
  508. IN OUT PRPC_MESSAGE Message
  509. ) ;
  510. RPC_STATUS
  511. SendRequestOrResponse (
  512. IN OUT PRPC_MESSAGE Message,
  513. IN unsigned char PacketType
  514. );
  515. RPC_STATUS
  516. SendNextFragment (
  517. void
  518. );
  519. void
  520. InquireObjectUuid (
  521. OUT RPC_UUID * ObjectUuid
  522. );
  523. RPC_STATUS
  524. ConvertToServerBinding (
  525. OUT RPC_BINDING_HANDLE __RPC_FAR * ServerBinding
  526. );
  527. RPC_STATUS
  528. ToStringBinding (
  529. OUT RPC_CHAR * * StringBinding
  530. );
  531. RPC_STATUS
  532. Cancel(
  533. void * ThreadHandle
  534. );
  535. unsigned
  536. TestCancel(
  537. );
  538. RPC_STATUS
  539. ImpersonateClient (
  540. );
  541. RPC_STATUS
  542. RevertToSelf (
  543. );
  544. virtual RPC_STATUS
  545. GetAuthorizationContext (
  546. IN BOOL ImpersonateOnReturn,
  547. IN AUTHZ_RESOURCE_MANAGER_HANDLE AuthzResourceManager,
  548. IN PLARGE_INTEGER pExpirationTime OPTIONAL,
  549. IN LUID Identifier,
  550. IN DWORD Flags,
  551. IN PVOID DynamicGroupArgs OPTIONAL,
  552. OUT PAUTHZ_CLIENT_CONTEXT_HANDLE pAuthzClientContext
  553. );
  554. virtual RPC_STATUS
  555. GetAssociationContextCollection (
  556. OUT ContextCollection **CtxCollection
  557. ) ;
  558. virtual RPC_STATUS
  559. IsClientLocal (
  560. OUT unsigned int * ClientLocalFlag
  561. ) ;
  562. virtual void
  563. IsClientDisconnected (
  564. OUT BOOL *ClientIsDisconnected
  565. );
  566. virtual RPC_STATUS
  567. InqTransportType(
  568. OUT unsigned int __RPC_FAR * Type
  569. ) ;
  570. void
  571. ActivateCall (
  572. );
  573. virtual void
  574. FreeObject (
  575. );
  576. virtual void
  577. RemoveReference (
  578. );
  579. void * operator new (
  580. size_t allocBlock,
  581. unsigned int xtraBytes
  582. );
  583. void
  584. CleanupCall (
  585. );
  586. void CleanupCallAndSendFault (IN RPC_STATUS Status,
  587. IN int DidNotExecute);
  588. virtual RPC_STATUS
  589. InqConnection (
  590. OUT void **ConnId,
  591. OUT BOOL *pfFirstCall
  592. );
  593. void
  594. AbortCall (
  595. )
  596. {
  597. CallMutex.Request();
  598. CurrentState = CallAborted;
  599. AsyncStatus = RPC_S_CALL_FAILED;
  600. // Wake up the thread that was flow controlled, if any
  601. if (fChoked == 1)
  602. {
  603. // Raising event for choked OSF_SCALL
  604. fChoked = 0;
  605. SyncEvent.Raise();
  606. CallMutex.Clear();
  607. // Since this is a pipe call, cleanup will be done on the send
  608. // thread; so return.
  609. return;
  610. }
  611. CallMutex.Clear();
  612. if (fCallDispatched == 0)
  613. {
  614. CleanupCall();
  615. //
  616. // Remove the reply reference
  617. //
  618. RemoveReference();
  619. //
  620. // Remove the dispatch reference
  621. //
  622. RemoveReference();
  623. return;
  624. }
  625. if (CallStack > 0)
  626. {
  627. SyncEvent.Raise();
  628. }
  629. }
  630. virtual RPC_STATUS
  631. InqSecurityContext (
  632. OUT void **SecurityContextHandle
  633. );
  634. inline BOOL
  635. IsSecure(
  636. void
  637. );
  638. inline void DeactivateCall(void)
  639. {
  640. if (DebugCell)
  641. {
  642. DebugCell->Status = csAllocated;
  643. // take down the async and pipe call flags
  644. // since they are per call instance
  645. DebugCell->CallFlags &= ~(DBGCELL_ASYNC_CALL | DBGCELL_PIPE_CALL);
  646. }
  647. }
  648. RPC_STATUS
  649. InqLocalConnAddress (
  650. IN OUT void *Buffer,
  651. IN OUT unsigned long *BufferSize,
  652. OUT unsigned long *AddressFormat
  653. );
  654. #if DBG
  655. virtual void
  656. InterfaceForCallDoesNotUseStrict (
  657. void
  658. );
  659. #endif
  660. void
  661. WakeUpPipeThreadIfNecessary (
  662. IN RPC_STATUS Status
  663. );
  664. inline RPC_STATUS
  665. TurnOnOffKeepAlives (
  666. IN BOOL TurnOn,
  667. IN ULONG Time,
  668. IN ULONG Interval
  669. );
  670. BOOL ProcessVerificationTrailer (
  671. IN rpc_sec_verification_trailer_command *FirstCommand,
  672. IN unsigned char *BufferEnd,
  673. IN RPC_MESSAGE *RpcMessage
  674. );
  675. BOOL CheckVerificationTrailer (
  676. IN unsigned char *BufferStart,
  677. IN unsigned char *BufferEnd,
  678. IN RPC_MESSAGE *RpcMessage
  679. );
  680. };
  681. inline void *
  682. OSF_SCALL::operator new (
  683. size_t allocBlock,
  684. unsigned int xtraBytes
  685. )
  686. {
  687. void * pvTemp = RpcpFarAllocate(allocBlock + xtraBytes);
  688. return(pvTemp);
  689. }
  690. inline BOOL
  691. OSF_SCALL::IsSyncCall (
  692. )
  693. {
  694. return !pAsync ;
  695. }
  696. NEW_SDICT2(OSF_SCALL, PVOID);
  697. class OSF_SCALL_AVRF : public OSF_SCALL
  698. /*++
  699. Class Description:
  700. This class overwrites an OSF_SCALL for use with RPC verifier.
  701. Methods will perform some checks.
  702. --*/
  703. {
  704. public:
  705. OSF_SCALL_AVRF (
  706. IN OSF_SCONNECTION *Connection,
  707. IN OUT RPC_STATUS *Status
  708. ) : OSF_SCALL(Connection, Status) {}
  709. RPC_STATUS
  710. ImpersonateClient (
  711. )
  712. {
  713. // If we are running with RPC veirfier and fault injection is enabled
  714. // for RpcImpersonateClient, see if we should fail it.
  715. if (pRpcVerifierSettings->fFaultInjectImpersonateClient)
  716. {
  717. // See if enough time has passed to start the fault injection.
  718. if (!pRpcVerifierSettings->DelayFaultInjectImpersonateClient ||
  719. GetTickCount() - gProcessStartTime > pRpcVerifierSettings->DelayFaultInjectImpersonateClient*1000)
  720. {
  721. if (RndBool(pRpcVerifierSettings->ProbFaultInjectImpersonateClient))
  722. {
  723. return RPC_S_OUT_OF_MEMORY;
  724. }
  725. }
  726. }
  727. return OSF_SCALL::ImpersonateClient();
  728. }
  729. };
  730. typedef SECURITY_STATUS
  731. (SEC_ENTRY *SecpSetIPAddressFn)
  732. (
  733. PUCHAR lpIpAddress,
  734. ULONG cchIpAddress
  735. );
  736. class OSF_SCONNECTION : public SCONNECTION
  737. /*++
  738. Class Description:
  739. Fields:
  740. Association - Contains the association to which this connection
  741. belongs. This field will be zero until after the initial client
  742. bind request has been accepted.
  743. SavedHeader - Unbyte swapped header + - do that check sums work
  744. ServerInfo - Contains the pointers to the loadable transport
  745. routines for the transport type of this connection.
  746. ConnectionClosedFlag - Contains a flag which will be non-zero if
  747. the connection is closed, and zero otherwise.
  748. ReferenceCount - The open connection and each dispatched call
  749. own one reference.
  750. --*/
  751. {
  752. friend OSF_SCALL;
  753. friend OSF_ADDRESS;
  754. private:
  755. // data member ordering is optimized for locality
  756. // If you modify something, make sure that the section boundaries are
  757. // preserved. It is assumed that in the common case the OSF_SCALL is used
  758. // by a thread at a time. Ordering is by frequency of usage, regardless of
  759. // read/write
  760. // Most frequenty used section (>= 3 times per call)
  761. BOOL fExclusive;
  762. BOOL CachedSCallAvailable;
  763. CLIENT_AUTH_INFO AuthInfo; // actually, only the AuthLevel is used, but we don't want to
  764. // split it
  765. // ~2 times per call
  766. RPC_CONNECTION_TRANSPORT * ServerInfo;
  767. unsigned int AdditionalSpaceForSecurity;
  768. unsigned int ConnectionClosedFlag;
  769. public:
  770. RPC_TRANSPORT_CONNECTION TransConnection;
  771. private:
  772. SECURITY_CONTEXT * CurrentSecurityContext;
  773. // ~1 times per call
  774. OSF_ASSOCIATION * Association;
  775. OSF_ADDRESS *Address;
  776. unsigned long DataRep;
  777. unsigned long RpcSecurityBeingUsed;
  778. DCE_SECURITY_INFO DceSecurityInfo;
  779. OSF_SCALL *CachedSCall;
  780. OSF_SBINDING_DICT Bindings;
  781. DebugConnectionInfo *DebugCell;
  782. public:
  783. unsigned short MaxFrag;
  784. private:
  785. CellTag DebugCellTag;
  786. // actively used in non-nominal paths
  787. OSF_SCALL_DICT2 CallDict;
  788. MUTEX ConnMutex;
  789. SECURITY_CONTEXT_DICT SecurityContextDict;
  790. void * SavedHeader;
  791. unsigned long SavedHeaderSize;
  792. // not used or used few times
  793. unsigned AuthContextId;
  794. unsigned long SecurityContextAltered;
  795. unsigned long CurrentCallId;
  796. BOOL AuthContinueNeeded;
  797. BOOL fDontFlush;
  798. DCE_INIT_SECURITY_INFO InitSecurityInfo;
  799. BOOL fKeepalivesTurnedOn;
  800. static const unsigned int ClientSupportsHeaderSigning = 1;
  801. // can be ClientSupportsHeaderSigning. Not protected from multithreaded access
  802. CompositeFlags Flags;
  803. static DLL *Secur32Dll;
  804. static SecpSetIPAddressFn SecpSetIPAddressFnPtr;
  805. public:
  806. BOOL fFirstCall;
  807. BOOL fCurrentlyDispatched;
  808. QUEUE CallQueue;
  809. OSF_SCONNECTION (
  810. IN OSF_ADDRESS * TheAddress,
  811. IN RPC_CONNECTION_TRANSPORT * ServerInfo,
  812. IN OUT RPC_STATUS * RpcStatus
  813. );
  814. ~OSF_SCONNECTION (
  815. );
  816. virtual RPC_STATUS
  817. TransSend (
  818. IN void * Buffer,
  819. IN unsigned int BufferLength
  820. );
  821. virtual RPC_STATUS
  822. TransAsyncSend (
  823. IN void * Buffer,
  824. IN unsigned int BufferLength,
  825. IN void *SendContext
  826. );
  827. virtual RPC_STATUS
  828. TransAsyncReceive (
  829. );
  830. virtual void
  831. FreeObject (
  832. );
  833. void
  834. AbortConnection (
  835. );
  836. unsigned int
  837. TransMaximumSend (
  838. );
  839. RPC_STATUS
  840. TransImpersonateClient (
  841. );
  842. void
  843. TransRevertToSelf (
  844. );
  845. void
  846. TransQueryClientProcess (
  847. OUT RPC_CLIENT_PROCESS_IDENTIFIER * ClientProcess
  848. );
  849. void
  850. TransQueryClientIpAddress (
  851. IN OUT RPC_CLIENT_IP_ADDRESS *ClientIpAddress
  852. );
  853. RPC_STATUS
  854. TransQueryClientNetworkAddress (
  855. OUT RPC_CHAR ** NetworkAddress
  856. );
  857. void
  858. SetDictKey (
  859. IN int DictKey
  860. );
  861. void * operator new (
  862. size_t allocBlock,
  863. unsigned int xtraBytes
  864. );
  865. RPC_STATUS
  866. SendFragment(
  867. IN OUT rpcconn_common *pFragment,
  868. IN unsigned int LastFragmentFlag,
  869. IN unsigned int HeaderSize,
  870. IN unsigned int MaxSecuritySize,
  871. IN unsigned int DataLength,
  872. IN unsigned int MaximumFragmentLength,
  873. IN unsigned char *MyReservedForSecurity,
  874. IN BOOL fAsync = 0,
  875. IN void *SendContext = 0
  876. ) ;
  877. RPC_STATUS
  878. InquireAuthClient (
  879. OUT RPC_AUTHZ_HANDLE * Privileges,
  880. OUT RPC_CHAR * * ServerPrincipalName, OPTIONAL
  881. OUT unsigned long * AuthenticationLevel,
  882. OUT unsigned long * AuthenticationService,
  883. OUT unsigned long * AuthorizationService,
  884. IN unsigned long Flags
  885. );
  886. RPC_STATUS
  887. InquireCallAttributes (
  888. IN OUT void *RpcCallAttributes
  889. );
  890. RPC_STATUS
  891. ImpersonateClient (
  892. );
  893. RPC_STATUS
  894. RevertToSelf (
  895. );
  896. RPC_STATUS
  897. GetAssociationContextCollection (
  898. OUT ContextCollection **AssociationContext
  899. );
  900. RPC_STATUS
  901. IsClientLocal (
  902. OUT unsigned int * ClientLocalFlag
  903. );
  904. void
  905. IsClientDisconnected (
  906. OUT BOOL *ClientIsDisconnected
  907. )
  908. {
  909. *ClientIsDisconnected = IsDeleted();
  910. }
  911. RPC_STATUS
  912. TransGetBuffer ( // Allocate a buffer of the specified size.
  913. OUT void * * Buffer,
  914. IN unsigned int BufferLength
  915. );
  916. virtual void
  917. TransFreeBuffer ( // Free a buffer.
  918. IN void * Buffer
  919. );
  920. int
  921. AssociationRequested (
  922. IN rpcconn_bind * BindPacket,
  923. IN unsigned int BindPacketLength
  924. );
  925. RPC_STATUS
  926. EatAuthInfoFromPacket (
  927. IN rpcconn_request * Request,
  928. IN OUT int * RequestLength,
  929. IN OUT void * *SavedHeader,
  930. IN OUT unsigned long *SavedHeaderSize
  931. );
  932. int // Indicates success (0), or an internal error code.
  933. AlterContextRequested ( // Process the alter context request. Send
  934. // a reply.
  935. IN rpcconn_alter_context * pAlterContext,
  936. IN unsigned int culAlterContextLength
  937. );
  938. int // Indicates success (0), or an internal error code.
  939. SendBindNak ( // Construct and send the bind nak packet using the
  940. // specified reject reason.
  941. IN p_reject_reason_t reject_reason,
  942. IN unsigned long CallId
  943. );
  944. inline
  945. SECURITY_CONTEXT *
  946. FindSecurityContext(
  947. unsigned long Id,
  948. unsigned long Level,
  949. unsigned long Svc
  950. );
  951. BOOL
  952. MaybeQueueThisCall (
  953. IN OSF_SCALL *ThisCall
  954. );
  955. void
  956. AbortQueuedCalls (
  957. );
  958. void
  959. DispatchQueuedCalls (
  960. );
  961. inline BOOL IsExclusive(void)
  962. {
  963. return fExclusive;
  964. }
  965. inline void SetClientSupportsHeaderSigningFlag(void)
  966. {
  967. Flags.SetFlagUnsafe(ClientSupportsHeaderSigning);
  968. }
  969. inline void ClearClientSupportsHeaderSigningFlag(void)
  970. {
  971. Flags.ClearFlagInterlocked(ClientSupportsHeaderSigning);
  972. }
  973. inline BOOL GetClientSupportsHeaderSigningFlag(void)
  974. {
  975. return Flags.GetFlag(ClientSupportsHeaderSigning);
  976. }
  977. private:
  978. int
  979. ProcessPContextList (
  980. IN OSF_ADDRESS * Address,
  981. IN p_cont_list_t * PContextList,
  982. IN OUT unsigned int * PContextListLength,
  983. OUT p_result_list_t * ResultList
  984. );
  985. RPC_STATUS
  986. GetServerPrincipalName (
  987. IN unsigned long Flags,
  988. OUT RPC_CHAR **ServerPrincipalName OPTIONAL
  989. );
  990. UINT
  991. CalculateAdditionalSpaceForSecurity (
  992. IN ULONG AuthenticationLevel,
  993. IN ULONG AuthenticationService
  994. );
  995. RPC_STATUS EnsureSecur32DllLoaded (
  996. void
  997. );
  998. public:
  999. void
  1000. SendFault (
  1001. IN RPC_STATUS Status,
  1002. IN int DidNotExecute,
  1003. IN unsigned long CallId,
  1004. IN p_context_id_t p_cont_id = 0
  1005. );
  1006. BOOL
  1007. PickleEEInfoIntoPacket (
  1008. IN size_t PickleStartOffset,
  1009. OUT PVOID *Packet,
  1010. OUT size_t *PacketSize);
  1011. OSF_ASSOCIATION *
  1012. TheAssociation (
  1013. ) {return(Association);}
  1014. void
  1015. RemoveFromAssociation (
  1016. );
  1017. virtual RPC_STATUS
  1018. InqTransportType(
  1019. OUT unsigned int __RPC_FAR * Type
  1020. ) ;
  1021. OSF_SBINDING *
  1022. LookupBinding (
  1023. IN p_context_id_t PresentContextId
  1024. );
  1025. inline void
  1026. CleanupPac(
  1027. );
  1028. void
  1029. ProcessReceiveComplete (
  1030. IN RPC_STATUS EventStatus,
  1031. IN BUFFER Buffer,
  1032. IN UINT BufferLength
  1033. );
  1034. void
  1035. FreeSCall (
  1036. IN OSF_SCALL *SCall,
  1037. IN BOOL fRemove = 0
  1038. );
  1039. OSF_SCALL *
  1040. FindCall (
  1041. unsigned long CallId
  1042. );
  1043. inline RPC_STATUS
  1044. InqLocalConnAddress (
  1045. IN OUT void *Buffer,
  1046. IN OUT unsigned long *BufferSize,
  1047. OUT unsigned long *AddressFormat
  1048. )
  1049. {
  1050. // Querying the local address has some transient
  1051. // effects on the Winsock options for the connection.
  1052. // We cannot do this on non-exclusive connections
  1053. // as it may affect calls in progress
  1054. if (ServerInfo->QueryLocalAddress && fExclusive)
  1055. {
  1056. return ServerInfo->QueryLocalAddress(TransConnection,
  1057. Buffer,
  1058. BufferSize,
  1059. AddressFormat);
  1060. }
  1061. else
  1062. return RPC_S_CANNOT_SUPPORT;
  1063. }
  1064. RPC_STATUS
  1065. TurnOnOffKeepAlives (
  1066. IN BOOL TurnOn,
  1067. IN ULONG Timeout,
  1068. IN ULONG Interval
  1069. );
  1070. inline BOOL IsHttpTransport (
  1071. void
  1072. )
  1073. {
  1074. return (ServerInfo->SetLastBufferToFree != NULL);
  1075. }
  1076. inline RPC_STATUS SetLastBufferToFree (
  1077. IN void *BufferToFree
  1078. )
  1079. {
  1080. ASSERT(ServerInfo->SetLastBufferToFree);
  1081. return ServerInfo->SetLastBufferToFree (TransConnection, BufferToFree);
  1082. }
  1083. RPC_STATUS
  1084. AcceptFirstTime (
  1085. IN SECURITY_CREDENTIALS * NewCredentials,
  1086. IN SECURITY_BUFFER_DESCRIPTOR PAPI * InputBufferDescriptor,
  1087. IN OUT SECURITY_BUFFER_DESCRIPTOR PAPI * OutputBufferDescriptor,
  1088. IN unsigned long AuthenticationLevel,
  1089. IN unsigned long DataRepresentation,
  1090. IN unsigned long NewContextNeededFlag
  1091. );
  1092. RPC_STATUS
  1093. AcceptThirdLeg (
  1094. IN unsigned long DataRepresentation,
  1095. IN SECURITY_BUFFER_DESCRIPTOR PAPI * BufferDescriptor,
  1096. OUT SECURITY_BUFFER_DESCRIPTOR PAPI * OutBufferDescriptor
  1097. );
  1098. };
  1099. inline OSF_SCALL *
  1100. OSF_SCONNECTION::FindCall (
  1101. unsigned long CallId
  1102. )
  1103. {
  1104. OSF_SCALL *SCall;
  1105. ConnMutex.Request();
  1106. SCall = CallDict.Find(ULongToPtr(CallId));
  1107. if (SCall)
  1108. {
  1109. SCall->AddReference(); // CALL++
  1110. }
  1111. ConnMutex.Clear();
  1112. return SCall;
  1113. }
  1114. inline void *
  1115. OSF_SCONNECTION::operator new (
  1116. size_t allocBlock,
  1117. unsigned int xtraBytes
  1118. )
  1119. {
  1120. void * pvTemp = RpcpFarAllocate(allocBlock + xtraBytes);
  1121. return(pvTemp);
  1122. }
  1123. inline void
  1124. OSF_SCONNECTION::CleanupPac (
  1125. )
  1126. {
  1127. if ((CurrentSecurityContext != 0) && (AuthInfo.PacHandle != 0))
  1128. {
  1129. CurrentSecurityContext->DeletePac( AuthInfo.PacHandle );
  1130. AuthInfo.PacHandle = 0;
  1131. }
  1132. }
  1133. inline
  1134. SECURITY_CONTEXT *
  1135. OSF_SCONNECTION::FindSecurityContext(
  1136. unsigned long Id,
  1137. unsigned long Level,
  1138. unsigned long Svc
  1139. )
  1140. {
  1141. SECURITY_CONTEXT *Sec;
  1142. DictionaryCursor cursor;
  1143. SecurityContextDict.Reset(cursor);
  1144. while ( (Sec = SecurityContextDict.Next(cursor)) != 0 )
  1145. {
  1146. if ( (Sec->AuthContextId == Id)
  1147. &&(Sec->AuthenticationLevel == Level)
  1148. &&(Sec->AuthenticationService == Svc) )
  1149. {
  1150. break;
  1151. }
  1152. }
  1153. return (Sec);
  1154. }
  1155. inline RPC_STATUS
  1156. OSF_SCONNECTION::InqTransportType(
  1157. OUT unsigned int __RPC_FAR * Type
  1158. )
  1159. {
  1160. *Type = TRANSPORT_TYPE_CN ;
  1161. return (RPC_S_OK) ;
  1162. }
  1163. inline RPC_STATUS
  1164. OSF_SCALL::InquireAuthClient (
  1165. OUT RPC_AUTHZ_HANDLE * Privileges,
  1166. OUT RPC_CHAR * * ServerPrincipalName, OPTIONAL
  1167. OUT unsigned long * AuthenticationLevel,
  1168. OUT unsigned long * AuthenticationService,
  1169. OUT unsigned long * AuthorizationService,
  1170. IN unsigned long Flags
  1171. )
  1172. {
  1173. return Connection->InquireAuthClient(Privileges,
  1174. ServerPrincipalName,
  1175. AuthenticationLevel,
  1176. AuthenticationService,
  1177. AuthorizationService,
  1178. Flags);
  1179. }
  1180. inline RPC_STATUS
  1181. OSF_SCALL::InquireCallAttributes (
  1182. IN OUT void *RpcCallAttributes
  1183. )
  1184. {
  1185. return Connection->InquireCallAttributes(RpcCallAttributes);
  1186. }
  1187. inline RPC_STATUS
  1188. OSF_SCALL::IsClientLocal (
  1189. OUT unsigned int * ClientLocalFlag
  1190. )
  1191. {
  1192. return Connection->IsClientLocal(ClientLocalFlag);
  1193. }
  1194. inline void
  1195. OSF_SCALL::IsClientDisconnected (
  1196. OUT BOOL *ClientIsDisconnected
  1197. )
  1198. {
  1199. Connection->IsClientDisconnected(ClientIsDisconnected);
  1200. }
  1201. inline RPC_STATUS
  1202. OSF_SCALL::InqTransportType(
  1203. OUT unsigned int __RPC_FAR * Type
  1204. )
  1205. {
  1206. return Connection->InqTransportType(Type);
  1207. }
  1208. inline RPC_STATUS
  1209. OSF_SCALL::InqSecurityContext (
  1210. OUT void **SecurityContextHandle
  1211. )
  1212. {
  1213. *SecurityContextHandle = Connection->CurrentSecurityContext->InqSecurityContext();
  1214. return RPC_S_OK;
  1215. }
  1216. inline BOOL
  1217. OSF_SCALL::IsSecure(
  1218. void
  1219. )
  1220. {
  1221. return (Connection->CurrentSecurityContext != NULL);
  1222. }
  1223. inline void
  1224. OSF_SCALL::ActivateCall (
  1225. )
  1226. {
  1227. CallStack = 0;
  1228. ObjectUuidSpecified = 0;
  1229. CallOrphaned = 0;
  1230. CurrentBuffer = 0;
  1231. CurrentBufferLength = 0 ;
  1232. CurrentOffset = 0;
  1233. AsyncStatus = RPC_S_OK;
  1234. Address = Connection->Address;
  1235. fPipeCall = 0;
  1236. fCallDispatched = 0;
  1237. DispatchBuffer = 0;
  1238. DispatchBufferOffset = 0;
  1239. AllocHint = 0;
  1240. RcvBufferLength = 0;
  1241. CurrentState = NewRequest;
  1242. FirstFrag = 1;
  1243. pAsync = 0;
  1244. CallingThread = 0;
  1245. CachedAPCInfoAvailable = 1;
  1246. NestingCall = 0;
  1247. FirstSend = 1;
  1248. NeededLength = 0;
  1249. LastBuffer = 0;
  1250. MaxSecuritySize = 0;
  1251. MaximumFragmentLength = Connection->MaxFrag;
  1252. fChoked = 0;
  1253. fPeerChoked = 0;
  1254. fSecurityFailure = 0;
  1255. DispatchFlags = RPC_BUFFER_COMPLETE;
  1256. CurrentBinding = 0;
  1257. fAsyncPipeCall = 0;
  1258. fNotifyOnSendComplete = 0;
  1259. if (DebugCell)
  1260. {
  1261. DebugCell->Status = csActive;
  1262. }
  1263. //
  1264. // Start out with two references. One for the dispatch
  1265. // and the other for the reply. This overrides the default
  1266. // which is one reference.
  1267. //
  1268. //
  1269. // Try changing this to a better interlocked operation
  1270. //
  1271. // we have the following special case to take care of:
  1272. // for performance reasons, the previous call will make
  1273. // itself available before it takes down its references.
  1274. // We may start piling our references on top of its
  1275. // references, thus preventing the refcount from dropping
  1276. // to zero, and leaving one extra refcount on the connection
  1277. // (because the call will drop its refcount on the connection
  1278. // only when its own refcount goes to 0). This if statement
  1279. // will detect when this special case happens, and will
  1280. // drop the connection refcount for the previous call
  1281. if ((AddReference() > 1) && (Connection->CachedSCall == this) && (Connection->IsExclusive()))
  1282. Connection->RemoveReference();
  1283. AddReference();
  1284. }
  1285. inline void
  1286. OSF_SCALL::RemoveReference (
  1287. )
  1288. {
  1289. OSF_SCALL *DeletedCall;
  1290. int refcount;
  1291. if (Connection->fExclusive)
  1292. {
  1293. REFERENCED_OBJECT::RemoveReference();
  1294. }
  1295. else
  1296. {
  1297. Connection->ConnMutex.Request();
  1298. refcount = RefCount.Decrement();
  1299. LogEvent(SU_SCALL, EV_DEC, this, 0, refcount, 1);
  1300. if (refcount == 0)
  1301. {
  1302. DeletedCall = Connection->CallDict.Delete(ULongToPtr(CallId));
  1303. Connection->ConnMutex.Clear();
  1304. ASSERT(DeletedCall == 0 || DeletedCall == this);
  1305. FreeObject();
  1306. //
  1307. // Warning: The SCALL could have been nuked at this point.
  1308. // DO NOT touch the SCALL after this
  1309. //
  1310. }
  1311. else
  1312. {
  1313. Connection->ConnMutex.Clear();
  1314. }
  1315. }
  1316. }
  1317. inline void
  1318. OSF_SCALL::CleanupCall (
  1319. )
  1320. {
  1321. BUFFER Buffer;
  1322. unsigned int ignore;
  1323. BOOL fMutexTaken = FALSE;
  1324. BOOL IsExclusiveConnection = Connection->IsExclusive();
  1325. if (pAsync)
  1326. {
  1327. DoPostDispatchProcessing();
  1328. ASSERT(fCallDispatched);
  1329. FreeBufferDo(DispatchBuffer);
  1330. if (IsExclusiveConnection)
  1331. {
  1332. CurrentBinding->GetInterface()->EndCall(0, 1);
  1333. if (CurrentBinding->GetInterface()->IsAutoListenInterface())
  1334. {
  1335. // This is the path where async calls complete.
  1336. // We need to decrement CallNumber.
  1337. CurrentBinding->GetInterface()->EndAutoListenCall(TRUE);
  1338. }
  1339. }
  1340. }
  1341. if (fCallDispatched == 0 && DispatchBuffer)
  1342. {
  1343. FreeBufferDo(DispatchBuffer);
  1344. }
  1345. Connection->CleanupPac();
  1346. DeactivateCall();
  1347. // For non-exclusive pipe calls we need to make the call available and
  1348. // free the buffers within a critical section. This ensures that another
  1349. // thread will not pick up the available call and start adding buffers to the
  1350. // queue while we are wiping it out.
  1351. if (fPipeCall && !IsExclusiveConnection)
  1352. {
  1353. CallMutex.Request();
  1354. fMutexTaken = TRUE;
  1355. }
  1356. if (IsExclusiveConnection)
  1357. {
  1358. Connection->CachedSCallAvailable = 1;
  1359. }
  1360. // Buffers must not be left over from this call
  1361. // If there are left over buffers, free them
  1362. if (!BufferQueue.IsQueueEmpty())
  1363. {
  1364. if (fMutexTaken == FALSE)
  1365. CallMutex.Request();
  1366. while (Buffer = BufferQueue.TakeOffQueue(&ignore))
  1367. {
  1368. Connection->TransFreeBuffer((char *) Buffer-sizeof(rpcconn_response));
  1369. }
  1370. CallMutex.Clear();
  1371. fMutexTaken = FALSE;
  1372. }
  1373. if (fMutexTaken == TRUE)
  1374. CallMutex.Clear();
  1375. }
  1376. inline void
  1377. OSF_SCALL::FreeObject (
  1378. )
  1379. /*++
  1380. Function Name:CleanupCall
  1381. Parameters:
  1382. Description:
  1383. Returns:
  1384. --*/
  1385. {
  1386. LogEvent(SU_SCALL, EV_DELETE, this, 0, 0, 0);
  1387. Connection->FreeSCall(this);
  1388. }
  1389. inline RPC_STATUS
  1390. OSF_SCALL::InqConnection (
  1391. OUT void **ConnId,
  1392. OUT BOOL *pfFirstCall
  1393. )
  1394. {
  1395. ASSERT(Connection);
  1396. *ConnId = Connection;
  1397. if (InterlockedIncrement((LONG *) &(Connection->fFirstCall)) == 1)
  1398. {
  1399. *pfFirstCall = 1;
  1400. }
  1401. else
  1402. {
  1403. *pfFirstCall = 0;
  1404. }
  1405. return RPC_S_OK;
  1406. }
  1407. inline RPC_STATUS
  1408. OSF_SCALL::TurnOnOffKeepAlives (
  1409. IN BOOL TurnOn,
  1410. IN ULONG Time,
  1411. IN ULONG Interval
  1412. )
  1413. {
  1414. return Connection->TurnOnOffKeepAlives (TurnOn, Time, Interval);
  1415. }
  1416. class OSF_ASSOCIATION : public ASSOCIATION_HANDLE
  1417. {
  1418. private:
  1419. int ConnectionCount;
  1420. unsigned long AssociationGroupId;
  1421. int AssociationDictKey;
  1422. OSF_ADDRESS * Address;
  1423. RPC_CLIENT_PROCESS_IDENTIFIER ClientProcess;
  1424. public:
  1425. OSF_ASSOCIATION (
  1426. IN OSF_ADDRESS * TheAddress,
  1427. IN RPC_CLIENT_PROCESS_IDENTIFIER * ClientProcess,
  1428. OUT RPC_STATUS * Status
  1429. );
  1430. ~OSF_ASSOCIATION ( // Destructor.
  1431. );
  1432. void
  1433. AddConnection ( // Add a connection to the association.
  1434. void
  1435. );
  1436. // Remove a connection from the association without taking
  1437. // the mutex. Returns non-zero if 'this' is to be deleted
  1438. BOOL
  1439. RemoveConnectionUnsafe (
  1440. void
  1441. );
  1442. void
  1443. RemoveConnection ( // Remove a connection from the association.
  1444. void
  1445. );
  1446. int // Returns the association group id for this association.
  1447. AssocGroupId (
  1448. void
  1449. )
  1450. {
  1451. return(AssociationGroupId);
  1452. }
  1453. OSF_ADDRESS *
  1454. TheAddress (
  1455. void
  1456. )
  1457. {
  1458. return(Address);
  1459. }
  1460. int
  1461. IsMyAssocGroupId (
  1462. IN unsigned long PossibleAssocGroupId,
  1463. IN RPC_CLIENT_PROCESS_IDENTIFIER * ClientProcess
  1464. );
  1465. virtual RPC_STATUS CreateThread(void);
  1466. };
  1467. inline int
  1468. OSF_ASSOCIATION::IsMyAssocGroupId (
  1469. IN unsigned long PossibleAssocGroupId,
  1470. IN RPC_CLIENT_PROCESS_IDENTIFIER * ClientProcess
  1471. )
  1472. /*++
  1473. Routine Description:
  1474. We compare the supplied possible association group id against my
  1475. association group id in this routine.
  1476. Arguments:
  1477. PossibleAssocGroupId - Supplies a possible association group id to
  1478. compare against mine.
  1479. ClientProcess - Supplies the identifier for the client process at the
  1480. other end of the connection requesting this association.
  1481. Return Value:
  1482. Non-zero will be returned if the possible association group id is the
  1483. same as my association group id.
  1484. --*/
  1485. {
  1486. if (PossibleAssocGroupId == AssociationGroupId)
  1487. {
  1488. if (this->ClientProcess.Compare(ClientProcess))
  1489. {
  1490. RpcpErrorAddRecord(EEInfoGCRuntime,
  1491. RPC_S_ENTRY_NOT_FOUND,
  1492. EEInfoDLOSF_ASSOCIATION__IsMyAssocGroupId10,
  1493. this->ClientProcess.GetDebugULongLong1(),
  1494. this->ClientProcess.GetDebugULongLong2(),
  1495. ClientProcess->GetDebugULongLong1(),
  1496. ClientProcess->GetDebugULongLong2()
  1497. );
  1498. return 0;
  1499. }
  1500. else
  1501. {
  1502. return 1;
  1503. }
  1504. }
  1505. else
  1506. return 0;
  1507. }
  1508. inline void
  1509. OSF_ASSOCIATION::AddConnection (
  1510. )
  1511. {
  1512. int HashBucketNumber;
  1513. // get the hashed bucket
  1514. HashBucketNumber = Address->GetHashBucketForAssociation(AssociationGroupId);
  1515. // verify the bucket is locked
  1516. Address->GetAssociationBucketMutex(HashBucketNumber)->VerifyOwned();
  1517. ConnectionCount ++;
  1518. }
  1519. inline void
  1520. OSF_SCONNECTION::RemoveFromAssociation (
  1521. )
  1522. /*++
  1523. Routine Description:
  1524. This connection will be removed from the association. We need to do
  1525. this so that context rundown will occur, even though the connection
  1526. has not been deleted yet.
  1527. --*/
  1528. {
  1529. if ( Association != 0 )
  1530. {
  1531. Association->RemoveConnection();
  1532. Association = 0;
  1533. }
  1534. }
  1535. extern RPC_TRANSPORT_INTERFACE_HEADER *
  1536. LoadableTransportServerInfo (
  1537. IN RPC_CHAR * DllName,
  1538. IN RPC_CHAR * RpcProtocolSequence,
  1539. OUT RPC_STATUS * Status
  1540. );
  1541. #endif // __OSFSVR_HXX__