Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1430 lines
34 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1990 - 1999
  6. //
  7. // File: handle.hxx
  8. //
  9. //--------------------------------------------------------------------------
  10. /* --------------------------------------------------------------------
  11. Microsoft OS/2 LAN Manager
  12. Copyright(c) Microsoft Corp., 1990
  13. -------------------------------------------------------------------- */
  14. /* --------------------------------------------------------------------
  15. File: handle.hxx
  16. Description:
  17. All of the classes in the handle management layer which are common to
  18. both the client runtime and the server runtime are in this file. The
  19. classes used only by the server runtime live in hndlsvr.hxx. The
  20. classes described here are independent of specific RPC protocol as
  21. well as transport.
  22. The class GENERIC_OBJECT is used is the root for the handle class hierarchy.
  23. It provides dynamic type checking for all handles.
  24. The MESSAGE_OBJECT class provides a common protocol for all of the handle
  25. types which know to send and receive messages.
  26. The CCONNECTION class represents a call handle on the client side.
  27. The BINDING_HANDLE class is a binding handle as used by a client to perform
  28. remote procedure calls.
  29. GENERIC_OBJECT
  30. MESSAGE_OBJECT
  31. CCONNECTION
  32. BINDING_HANDLE
  33. History :
  34. mikemon ??-??-?? Beginning of time (at least for this file).
  35. mikemon 12-28-90 Cleaned up the comments.
  36. Kamen Moutafov (kamenm) Jan-2000 Support for multiple transfer syntaxes
  37. Kamen Moutafov (KamenM) Dec 99 - Feb 2000 - Support for cell debugging stuff
  38. -------------------------------------------------------------------- */
  39. #ifndef __HANDLE_HXX__
  40. #define __HANDLE_HXX__
  41. // These are the types for all of the handles visible outside of the
  42. // RPC runtime. Since they are just defines, we might as well stick
  43. // the server handle types here as well.
  44. #define OBJECT_DELETED 0x00000001
  45. #define DG_CCALL_TYPE 0x00000004
  46. #define DG_SCALL_TYPE 0x00000008
  47. #define DG_BINDING_HANDLE_TYPE 0x00000010
  48. #define OSF_CCALL_TYPE 0x00000020
  49. #define OSF_SCALL_TYPE 0x00000040
  50. #define OSF_CCONNECTION_TYPE 0x00000080
  51. #define OSF_SCONNECTION_TYPE 0x00000100
  52. #define OSF_CASSOCIATION_TYPE 0x00000200
  53. #define OSF_ASSOCIATION_TYPE 0x00000400
  54. #define OSF_ADDRESS_TYPE 0x00000800
  55. #define LRPC_CCALL_TYPE 0x00001000
  56. #define LRPC_SCALL_TYPE 0x00002000
  57. #define LRPC_CASSOCIATION_TYPE 0x00004000
  58. #define LRPC_SASSOCIATION_TYPE 0x00008000
  59. #define LRPC_BINDING_HANDLE_TYPE 0x00010000
  60. #define SVR_BINDING_HANDLE_TYPE 0x00020000
  61. #define DG_CCONNECTION_TYPE 0x00040000
  62. #define DG_SCONNECTION_TYPE 0x00080000
  63. #define OSF_BINDING_HANDLE_TYPE 0x00100000
  64. #define DG_CALLBACK_TYPE 0x00200000
  65. #define DG_ADDRESS_TYPE 0x00400000
  66. #define LRPC_ADDRESS_TYPE 0x00800000
  67. #define DG_CASSOCIATION_TYPE 0x01000000
  68. #define DG_SASSOCIATION_TYPE 0x02000000
  69. #define CONTEXT_TYPE 0x04000000
  70. #define HTTP_CLIENT_IN_CHANNEL 0x10000000
  71. #define HTTP_CLIENT_OUT_CHANNEL 0x10000010
  72. typedef int HANDLE_TYPE;
  73. //
  74. // define the base types
  75. //
  76. #define CALL_TYPE (DG_CCALL_TYPE \
  77. | DG_SCALL_TYPE \
  78. | OSF_CCALL_TYPE \
  79. | OSF_SCALL_TYPE \
  80. | LRPC_CCALL_TYPE \
  81. | LRPC_SCALL_TYPE \
  82. | DG_CALLBACK_TYPE)
  83. #define BINDING_HANDLE_TYPE (OSF_BINDING_HANDLE_TYPE \
  84. | DG_BINDING_HANDLE_TYPE \
  85. | LRPC_BINDING_HANDLE_TYPE \
  86. | SVR_BINDING_HANDLE_TYPE )
  87. #define CCALL_TYPE (DG_CCALL_TYPE \
  88. | OSF_CCALL_TYPE \
  89. | LRPC_CCALL_TYPE)
  90. #define SCALL_TYPE (DG_SCALL_TYPE \
  91. | DG_CALLBACK_TYPE \
  92. | OSF_SCALL_TYPE \
  93. | LRPC_SCALL_TYPE )
  94. typedef struct {
  95. RPC_BINDING_HANDLE hCall;
  96. PRPC_ASYNC_STATE pAsync;
  97. void *Context;
  98. RPC_ASYNC_EVENT Event;
  99. } RPC_APC_INFO;
  100. RPC_HTTP_TRANSPORT_CREDENTIALS_W *ConvertToUnicodeHttpTransportCredentials (
  101. const IN RPC_HTTP_TRANSPORT_CREDENTIALS_A *SourceCredentials
  102. );
  103. void WipeOutAuthIdentity (
  104. IN SEC_WINNT_AUTH_IDENTITY_W *AuthIdentity
  105. );
  106. void FreeHttpTransportCredentials (
  107. IN RPC_HTTP_TRANSPORT_CREDENTIALS_W *Credentials
  108. );
  109. RPC_HTTP_TRANSPORT_CREDENTIALS_W *DuplicateHttpTransportCredentials (
  110. const IN RPC_HTTP_TRANSPORT_CREDENTIALS_W *SourceCredentials
  111. );
  112. RPC_STATUS DecryptAuthIdentity (
  113. IN SEC_WINNT_AUTH_IDENTITY_W *AuthIdentity
  114. );
  115. /* --------------------------------------------------------------------
  116. GENERIC_OBJECT :
  117. The GENERIC_OBJECT class serves as the base for all handles used by the
  118. RPC runtime. It provides type checking of handles. The type checking
  119. is provided in two different ways:
  120. (1) At the front of every object is an unsigned long. This is set to a
  121. specific (magic) value which is checked whenever the handle is validated.
  122. NOTE: Every handle which the user gives us is validated.
  123. (2) We also can dynamically determine the type of the object.
  124. -------------------------------------------------------------------- */
  125. // This is the magic value we stick in the front of every valid
  126. // GENERIC_OBJECT.
  127. #define MAGICLONG 0x89ABCDEF
  128. #define MAGICLONGDEAD 0x99DEAD99
  129. extern RPC_STATUS CaptureLogonid( LUID * LogonId );
  130. extern RPC_STATUS CaptureModifiedId(LUID *ModifiedId);
  131. class THREAD;
  132. class NO_VTABLE GENERIC_OBJECT
  133. {
  134. // This instance variable contains a magic value which is used to
  135. // validate handles.
  136. unsigned long MagicLong;
  137. protected:
  138. HANDLE_TYPE ObjectType;
  139. GENERIC_OBJECT ()
  140. {
  141. MagicLong = MAGICLONG;
  142. #ifdef DEBUGRPC
  143. ObjectType = 0;
  144. #endif
  145. }
  146. ~GENERIC_OBJECT ()
  147. {
  148. MagicLong = MAGICLONGDEAD;
  149. #ifdef DEBUGRPC
  150. ASSERT( ObjectType );
  151. #endif
  152. }
  153. public:
  154. // Predicate to test for a valid handle. Note that HandleType may
  155. // specify more than one type of handle. This works because the handle
  156. // types are specified as bits in an unsigned number.
  157. unsigned int // Return zero (0) if the handle is valid and its type
  158. // is one of the types specified by the HandleType argument;
  159. // otherwise, the handle is invalid, and one (1) is returned.
  160. InvalidHandle ( // Check for an invalid handle.
  161. IN HANDLE_TYPE HandleType // Bitmap of one or more handle types to
  162. // be used in validating the handle.
  163. );
  164. HANDLE_TYPE Type (HANDLE_TYPE BaseType)
  165. {
  166. #ifdef DEBUGRPC
  167. ASSERT( ObjectType );
  168. #endif
  169. return (ObjectType & BaseType);
  170. }
  171. virtual void DoNothing(void)
  172. {
  173. }
  174. };
  175. class NO_VTABLE REFERENCED_OBJECT : public GENERIC_OBJECT
  176. {
  177. public:
  178. inline
  179. REFERENCED_OBJECT (
  180. ) : RefCount(1) {}
  181. virtual
  182. ~REFERENCED_OBJECT (
  183. ) {}
  184. virtual void
  185. ProcessSendComplete (
  186. IN RPC_STATUS EventStatus,
  187. IN BUFFER Buffer
  188. ) {ASSERT(0);}
  189. virtual void
  190. FreeObject (
  191. );
  192. int
  193. AddReference (
  194. );
  195. inline void SingleThreadedAddReference(void)
  196. {
  197. RefCount.SingleThreadedIncrement();
  198. }
  199. inline void SingleThreadedAddMultipleReferences(long nReferences)
  200. {
  201. RefCount.SingleThreadedIncrement(nReferences);
  202. }
  203. virtual void
  204. RemoveReference (
  205. );
  206. void
  207. Delete (
  208. );
  209. void
  210. Destroy (
  211. );
  212. BOOL
  213. IsDeleted (
  214. );
  215. void SetNotDeleted(void)
  216. {
  217. ObjectType &= ~OBJECT_DELETED;
  218. }
  219. void
  220. SetReferenceCount (
  221. IN int Count
  222. ) {RefCount.SetInteger(Count);}
  223. protected:
  224. BOOL SetDeletedFlag(void)
  225. {
  226. int savedObjectType = ObjectType;
  227. if (((savedObjectType & OBJECT_DELETED) == 0) &&
  228. InterlockedCompareExchange((long *)&ObjectType, savedObjectType | OBJECT_DELETED, savedObjectType) == savedObjectType)
  229. {
  230. LogEvent(SU_REFOBJ, EV_DELETE, this, IntToPtr(savedObjectType), RefCount.GetInteger(), 1, 1);
  231. return TRUE;
  232. }
  233. return FALSE;
  234. }
  235. INTERLOCKED_INTEGER RefCount;
  236. };
  237. inline void
  238. REFERENCED_OBJECT::FreeObject (
  239. )
  240. {
  241. delete this;
  242. }
  243. inline int
  244. REFERENCED_OBJECT::AddReference (
  245. )
  246. {
  247. int MyCount;
  248. MyCount = RefCount.Increment();
  249. LogEvent(SU_REFOBJ, EV_INC, this, IntToPtr(ObjectType), MyCount, 1, 1);
  250. return MyCount;
  251. }
  252. inline void
  253. REFERENCED_OBJECT::RemoveReference (
  254. )
  255. {
  256. int MyCount;
  257. LogEvent(SU_REFOBJ, EV_DEC, this, IntToPtr(ObjectType), RefCount.GetInteger(), 1, 1);
  258. MyCount = RefCount.Decrement();
  259. ASSERT(MyCount >= 0);
  260. if (0 == MyCount)
  261. {
  262. FreeObject();
  263. }
  264. }
  265. inline void
  266. REFERENCED_OBJECT::Delete (
  267. )
  268. {
  269. int MyCount;
  270. if (SetDeletedFlag())
  271. {
  272. MyCount = RefCount.Decrement();
  273. ASSERT(MyCount);
  274. }
  275. }
  276. inline void
  277. REFERENCED_OBJECT::Destroy (
  278. )
  279. {
  280. int MyCount;
  281. if (SetDeletedFlag())
  282. {
  283. RemoveReference();
  284. }
  285. }
  286. inline BOOL
  287. REFERENCED_OBJECT::IsDeleted (
  288. )
  289. {
  290. return (ObjectType & OBJECT_DELETED);
  291. }
  292. class BINDING_HANDLE; // forward
  293. /* --------------------------------------------------------------------
  294. MESSAGE_OBJECT :
  295. The MESSAGE_OBJECT class provides the common protocol for all handle types
  296. which can be used to send messages. The common protocol defined includes
  297. message routines, buffer management routines, and routines for querying
  298. calls and bindings.
  299. -------------------------------------------------------------------- */
  300. class NO_VTABLE MESSAGE_OBJECT : public REFERENCED_OBJECT
  301. {
  302. public:
  303. virtual RPC_STATUS // Value to be returned by SendReceive API.
  304. SendReceive ( // Perform a send-receive operation in a handle specific
  305. // way.
  306. IN OUT PRPC_MESSAGE Message
  307. ) = 0;
  308. // Perform a send operationin a handle specific way
  309. // this API is used in conjunction with pipes
  310. virtual RPC_STATUS
  311. Send (
  312. IN OUT PRPC_MESSAGE Message
  313. ) = 0;
  314. // Perform a receive in a handle specific way
  315. // this API is used in conjunction with pipes
  316. virtual RPC_STATUS
  317. Receive (
  318. IN OUT PRPC_MESSAGE Message,
  319. IN unsigned int Size
  320. ) = 0;
  321. // Perform a send operationin a handle specific way
  322. // this API is used in conjunction with pipes
  323. virtual RPC_STATUS
  324. AsyncSend (
  325. IN OUT PRPC_MESSAGE Message
  326. ) ;
  327. // Perform a receive in a handle specific way
  328. // this API is used in conjunction with pipes
  329. virtual RPC_STATUS
  330. AsyncReceive (
  331. IN OUT PRPC_MESSAGE Message,
  332. IN unsigned int Size
  333. ) ;
  334. virtual RPC_STATUS
  335. SetAsyncHandle (
  336. IN PRPC_ASYNC_STATE pAsync
  337. ) ;
  338. virtual RPC_STATUS
  339. AbortAsyncCall (
  340. IN PRPC_ASYNC_STATE pAsync,
  341. IN unsigned long ExceptionCode
  342. ) ;
  343. virtual RPC_STATUS
  344. GetCallStatus (
  345. ) ;
  346. // on the client side, Message->RpcInterfaceInformation
  347. // points to an RPC_CLIENT_INTERFACE structure. The
  348. // TransferSyntax member on in points to the transfer syntax preferred
  349. // by the stub, and on output is filled by the best estimate of the
  350. // runtime what transfer syntax will be optimal for the call. The
  351. // memory pointed by TransferSyntax on in is owned by the stub and
  352. // is guaranteed to be valid for the duration of the call. On out
  353. // this memory is owned by the runtime and should not be freed by the
  354. // stub. The runtime guarantees it is valid for the lifetime of the
  355. // call (i.e. until calling I_RpcFreeBuffer, or one of the I_Rpc
  356. // functions returns failure.
  357. // On the server side, Message->RpcInterfaceInformation points to
  358. // an RPC_SERVER_INTERFACE structure
  359. virtual RPC_STATUS
  360. NegotiateTransferSyntax (
  361. IN OUT PRPC_MESSAGE Message
  362. ) = 0;
  363. virtual RPC_STATUS // Value to be returned by RpcGetBuffer API.
  364. GetBuffer ( // Perform a buffer allocation operation in a handle specific
  365. // way.
  366. IN OUT PRPC_MESSAGE Message,
  367. IN UUID *ObjectUuid
  368. ) = 0;
  369. virtual void
  370. FreeBuffer ( // Perform a buffer deallocation operation in a handle
  371. // specific way.
  372. IN PRPC_MESSAGE Message
  373. ) = 0;
  374. // deallocate a buffer associated with pipes, in a handle specific way
  375. virtual void
  376. FreePipeBuffer (
  377. IN PRPC_MESSAGE Messsage
  378. ) ;
  379. // reallocate a buffer associated with pipes, in a handle specific way
  380. virtual RPC_STATUS
  381. ReallocPipeBuffer (
  382. IN PRPC_MESSAGE Message,
  383. IN unsigned int NewSize
  384. ) ;
  385. virtual RPC_STATUS
  386. BindingCopy (
  387. OUT BINDING_HANDLE * PAPI * DestinationBinding,
  388. IN unsigned int MaintainContext
  389. );
  390. virtual BOOL
  391. IsSyncCall (
  392. ) ;
  393. };
  394. inline void
  395. MESSAGE_OBJECT::FreePipeBuffer (
  396. IN PRPC_MESSAGE Messsage
  397. )
  398. {
  399. ASSERT(0) ;
  400. return ;
  401. }
  402. inline BOOL
  403. MESSAGE_OBJECT::IsSyncCall (
  404. )
  405. {
  406. return 1;
  407. }
  408. inline RPC_STATUS
  409. MESSAGE_OBJECT::GetCallStatus (
  410. )
  411. {
  412. ASSERT(0 && "improper MESSAGE_OBJECT member called\n");
  413. return (RPC_S_CANNOT_SUPPORT) ;
  414. }
  415. inline RPC_STATUS
  416. MESSAGE_OBJECT::AsyncSend (
  417. IN OUT PRPC_MESSAGE Message
  418. )
  419. {
  420. ASSERT(0 && "improper MESSAGE_OBJECT member called\n");
  421. return (RPC_S_CANNOT_SUPPORT) ;
  422. }
  423. inline RPC_STATUS
  424. MESSAGE_OBJECT::SetAsyncHandle (
  425. IN PRPC_ASYNC_STATE pAsync
  426. )
  427. {
  428. ASSERT(0 && "improper MESSAGE_OBJECT member called\n");
  429. return (RPC_S_CANNOT_SUPPORT) ;
  430. }
  431. inline RPC_STATUS
  432. MESSAGE_OBJECT::AbortAsyncCall (
  433. IN PRPC_ASYNC_STATE pAsync,
  434. IN unsigned long ExceptionCode
  435. )
  436. {
  437. ASSERT(0 && "improper MESSAGE_OBJECT member called\n");
  438. return (RPC_S_CANNOT_SUPPORT) ;
  439. }
  440. // Perform a receive in a handle specific way
  441. // this API is used in conjunction with pipes
  442. inline RPC_STATUS
  443. MESSAGE_OBJECT::AsyncReceive (
  444. IN OUT PRPC_MESSAGE Message,
  445. IN unsigned int Size
  446. )
  447. {
  448. ASSERT(0 && "improper MESSAGE_OBJECT member called\n");
  449. return (RPC_S_CANNOT_SUPPORT) ;
  450. }
  451. inline RPC_STATUS
  452. MESSAGE_OBJECT::ReallocPipeBuffer (
  453. IN PRPC_MESSAGE Messsage,
  454. IN unsigned int NewSize
  455. )
  456. {
  457. ASSERT(0 && "improper MESSAGE_OBJECT member called\n");
  458. return (RPC_S_CANNOT_SUPPORT) ;
  459. }
  460. class SECURITY_CREDENTIALS;
  461. struct CLIENT_AUTH_INFO
  462. {
  463. unsigned long AuthenticationLevel;
  464. unsigned long AuthenticationService;
  465. RPC_CHAR * ServerPrincipalName;
  466. union
  467. {
  468. RPC_AUTH_IDENTITY_HANDLE AuthIdentity; // Client-side only
  469. RPC_AUTHZ_HANDLE PacHandle; // Server-side only
  470. };
  471. unsigned long AuthorizationService;
  472. unsigned long IdentityTracking;
  473. unsigned long ImpersonationType;
  474. unsigned long Capabilities;
  475. unsigned long AdditionalTransportCredentialsType;
  476. void *AdditionalCredentials;
  477. LUID ModifiedId;
  478. BOOL DefaultLogonId;
  479. SECURITY_CREDENTIALS * Credentials;
  480. CLIENT_AUTH_INFO();
  481. CLIENT_AUTH_INFO::CLIENT_AUTH_INFO(
  482. const CLIENT_AUTH_INFO * myAuthInfo,
  483. RPC_STATUS PAPI * pStatus
  484. );
  485. ~CLIENT_AUTH_INFO();
  486. BOOL
  487. IsSupportedAuthInfo(
  488. const CLIENT_AUTH_INFO * AuthInfo,
  489. BOOL fNamedPipe = 0
  490. ) const;
  491. int
  492. CredentialsMatch(
  493. SECURITY_CREDENTIALS PAPI * Creds
  494. ) const;
  495. void ReferenceCredentials() const;
  496. // note that after this method is called, but before destruction of pTarget occurs,
  497. // PrepareForDestructionAfterShallowCopy must be called on target
  498. inline CLIENT_AUTH_INFO *ShallowCopyTo(CLIENT_AUTH_INFO *pTarget)
  499. {
  500. memcpy(pTarget, this, sizeof(CLIENT_AUTH_INFO));
  501. return pTarget;
  502. }
  503. inline void PrepareForDestructionAfterShallowCopy(void)
  504. {
  505. ServerPrincipalName = NULL;
  506. AdditionalCredentials = NULL;
  507. AdditionalTransportCredentialsType = 0;
  508. }
  509. };
  510. inline
  511. CLIENT_AUTH_INFO::CLIENT_AUTH_INFO(
  512. )
  513. {
  514. AuthenticationLevel = RPC_C_AUTHN_LEVEL_NONE;
  515. AuthenticationService = RPC_C_AUTHN_NONE;
  516. AuthorizationService = RPC_C_AUTHZ_NONE;
  517. ServerPrincipalName = 0;
  518. AuthIdentity = 0;
  519. Credentials = 0;
  520. ImpersonationType = RPC_C_IMP_LEVEL_IMPERSONATE;
  521. IdentityTracking = RPC_C_QOS_IDENTITY_STATIC;
  522. Capabilities = RPC_C_QOS_CAPABILITIES_DEFAULT;
  523. DefaultLogonId = 1;
  524. AdditionalTransportCredentialsType = 0;
  525. AdditionalCredentials = NULL;
  526. }
  527. #define LOW_BITS 0x0000007L
  528. #define NOT_MULTIPLE_OF_EIGHT(_x_) (_x_ & 0x00000007L)
  529. class NO_VTABLE CALL : public MESSAGE_OBJECT
  530. {
  531. public:
  532. CALL * NestingCall;
  533. PRPC_ASYNC_STATE pAsync ;
  534. long NotificationIssued;
  535. inline
  536. CALL(
  537. )
  538. {
  539. }
  540. // Perform a send operationin a handle specific way
  541. // this API is used in conjunction with pipes
  542. virtual RPC_STATUS
  543. Send (
  544. IN OUT PRPC_MESSAGE Message
  545. ) ;
  546. // Perform a receive in a handle specific way
  547. // this API is used in conjunction with pipes
  548. virtual RPC_STATUS
  549. Receive (
  550. IN OUT PRPC_MESSAGE Message,
  551. IN unsigned int Size
  552. ) ;
  553. virtual RPC_STATUS
  554. AsyncSend (
  555. IN OUT PRPC_MESSAGE Message
  556. ) ;
  557. virtual RPC_STATUS
  558. AsyncReceive (
  559. IN OUT PRPC_MESSAGE Message,
  560. IN unsigned int Size
  561. ) ;
  562. virtual RPC_STATUS
  563. SetAsyncHandle (
  564. IN PRPC_ASYNC_STATE pAsync
  565. ) ;
  566. virtual RPC_STATUS
  567. AbortAsyncCall (
  568. IN PRPC_ASYNC_STATE pAsync,
  569. IN unsigned long ExceptionCode
  570. ) ;
  571. virtual RPC_STATUS
  572. GetCallStatus (
  573. ) ;
  574. virtual void
  575. ProcessEvent (
  576. ) ;
  577. virtual RPC_STATUS
  578. CancelAsyncCall (
  579. IN BOOL fAbort
  580. );
  581. virtual void
  582. ProcessResponse (
  583. IN BOOL fDirectCall = 0
  584. ) ;
  585. virtual RPC_STATUS
  586. Cancel(
  587. void * ThreadHandle
  588. );
  589. virtual unsigned
  590. TestCancel(
  591. );
  592. virtual void
  593. FreeAPCInfo (
  594. IN RPC_APC_INFO *pAPCInfo
  595. ) ;
  596. virtual BOOL
  597. IssueNotification (
  598. IN RPC_ASYNC_EVENT Event = RpcCallComplete
  599. ) ;
  600. virtual RPC_STATUS
  601. InqSecurityContext (
  602. OUT void **SecurityContextHandle
  603. )
  604. {
  605. return RPC_S_CANNOT_SUPPORT;
  606. }
  607. protected:
  608. RPC_STATUS AsyncStatus ;
  609. RPC_APC_INFO CachedAPCInfo ;
  610. BOOL CachedAPCInfoAvailable ;
  611. THREAD *CallingThread ;
  612. BOOL
  613. QueueAPC (
  614. IN RPC_ASYNC_EVENT Event,
  615. IN void *Context = 0
  616. ) ;
  617. // Validates parameters and check whether actual
  618. // notification is necessary. 0 if none is necessary
  619. // or non-zero if notification is necessary. The
  620. // function is non-idempotent, and if called, and
  621. // returns non-zero, the main notification function
  622. // MUST be called (state corruption will occur
  623. // otherwise)
  624. BOOL
  625. IssueNotificationEntry (
  626. IN RPC_ASYNC_EVENT Event = RpcCallComplete
  627. );
  628. // do the actual notification. Caller MUST have
  629. // called IssueNotificationEntry before that, and
  630. // call this only IssueNotificationEntry returns
  631. // non-zero
  632. BOOL
  633. IssueNotificationMain (
  634. IN RPC_ASYNC_EVENT Event = RpcCallComplete
  635. );
  636. };
  637. inline RPC_STATUS
  638. CALL::GetCallStatus (
  639. )
  640. {
  641. return AsyncStatus ;
  642. }
  643. inline RPC_STATUS
  644. CALL::CancelAsyncCall (
  645. IN BOOL fAbort
  646. )
  647. {
  648. return RPC_S_OK;
  649. }
  650. inline RPC_STATUS
  651. CALL::SetAsyncHandle (
  652. IN PRPC_ASYNC_STATE pAsync
  653. )
  654. /*++
  655. Routine Description:
  656. This method is called by the stubs to associate an async handle with
  657. this CCALL.
  658. Arguments:
  659. pAsync - The async handle to association with this CCALL.
  660. Return Value:
  661. RPC_S_OK - Function succeeded
  662. RPC_S_OUT_OF_MEMORY - we ran out of memory
  663. --*/
  664. {
  665. if (pAsync->u.APC.hThread == 0)
  666. {
  667. pAsync->u.APC.hThread = RpcpGetThreadPointer()->ThreadHandle();
  668. }
  669. this->pAsync = pAsync ;
  670. return RPC_S_OK ;
  671. }
  672. class NO_VTABLE CCALL : public CALL
  673. //
  674. // This class represents a call on the client side. It implements
  675. // the pure virtual fns from class CALL.
  676. //
  677. {
  678. public:
  679. BOOL UuidSpecified;
  680. UUID ObjectUuid;
  681. inline
  682. CCALL(
  683. CLIENT_AUTH_INFO * myAuthInfo,
  684. RPC_STATUS __RPC_FAR * pStatus
  685. )
  686. {
  687. UuidSpecified = 0;
  688. }
  689. inline
  690. CCALL(
  691. )
  692. {
  693. }
  694. protected:
  695. // utility function which sets the common debug information for a client call
  696. RPC_STATUS SetDebugClientCallInformation(OUT DebugClientCallInfo **ppClientCallInfo,
  697. OUT CellTag *ClientCallInfoCellTag,
  698. OUT DebugCallTargetInfo **ppCallTargetInfo,
  699. OUT CellTag *CallTargetInfoCellTag,
  700. IN OUT PRPC_MESSAGE Message,
  701. IN DebugThreadInfo *ThreadDebugCell,
  702. IN CellTag ThreadCellTag);
  703. };
  704. RPC_STATUS
  705. DispatchCallback(
  706. IN PRPC_DISPATCH_TABLE DispatchTableCallback,
  707. IN OUT PRPC_MESSAGE Message,
  708. OUT RPC_STATUS PAPI * ExceptionCode
  709. );
  710. class TRANS_INFO; // forward
  711. class DCE_BINDING;
  712. /* --------------------------------------------------------------------
  713. BINDING_HANDLE :
  714. A BINDING_HANDLE is the binding handle used by clients to make remote
  715. procedure calls. We derive the BINDING_HANDLE class from the MESSAGE_OBJECT
  716. class because binding handles are used to send remote procedure calls.
  717. For some operating environments and transports
  718. we need to clean up the transports when the process ends.
  719. -------------------------------------------------------------------- */
  720. class NO_VTABLE BINDING_HANDLE : public MESSAGE_OBJECT
  721. /*++
  722. Class Description:
  723. Fields:
  724. Timeout - Contains the communications timeout for this binding
  725. handle.
  726. ObjectUuid - Contains the object uuid for this binding handle. The
  727. constructor will initialize this value to the null uuid.
  728. NullObjectUuidFlag - Contains a flag which indicates whether or
  729. not the object uuid for this binding handle is the null uuid.
  730. If this flag is non-zero, then this binding handle has the
  731. null uuid as its object uuid; otherwise, the object uuid is
  732. not the null uuid.
  733. EpLookupHandle - Contains the endpoint mapper lookup handle for
  734. this binding handle. This makes it possible to iterate through
  735. all of the endpoints in an endpoint mapper database by trying
  736. to make a remote procedure call, and then, when it fails, calling
  737. RpcBindingReset.
  738. BindingSetKey - Contains the key for this binding handle in the
  739. global set of binding handles.
  740. EntryNameSyntax - Contains the syntax of the entry name field of
  741. this object. This field will be zero if the binding handle
  742. was not imported or looked up.
  743. EntryName - Contains the entry name in the name service where this
  744. binding handle was imported or looked up from. This field will
  745. be zero if the binding handle was not imported or looked up.
  746. ClientAuthInfo - Contains the authentication and authorization information
  747. for this binding handle.
  748. --*/
  749. {
  750. private:
  751. RPC_UUID ObjectUuid;
  752. unsigned int Timeout;
  753. unsigned int NullObjectUuidFlag;
  754. unsigned long EntryNameSyntax;
  755. RPC_CHAR * EntryName;
  756. void PAPI * EpLookupHandle;
  757. ULONG_PTR * OptionsVector;
  758. protected:
  759. CLIENT_AUTH_INFO ClientAuthInfo;
  760. MUTEX BindingMutex;
  761. public:
  762. //
  763. // This is an opaque area of memory set aside for the transport
  764. // to manage transport specific options:
  765. //
  766. void PAPI * pvTransportOptions;
  767. BINDING_HANDLE (
  768. IN OUT RPC_STATUS *pStatus
  769. );
  770. public:
  771. virtual
  772. ~BINDING_HANDLE (
  773. );
  774. virtual RPC_STATUS
  775. BindingFree (
  776. ) = 0;
  777. RPC_STATUS
  778. Clone(
  779. IN BINDING_HANDLE * OriginalHandle
  780. );
  781. void
  782. InquireObjectUuid (
  783. OUT RPC_UUID PAPI * ObjectUuid
  784. );
  785. void
  786. SetObjectUuid (
  787. IN RPC_UUID PAPI * ObjectUuid
  788. );
  789. virtual RPC_STATUS
  790. PrepareBindingHandle (
  791. IN TRANS_INFO * TransInfo,
  792. IN DCE_BINDING * DceBinding
  793. ) = 0;
  794. virtual RPC_STATUS
  795. ToStringBinding (
  796. OUT RPC_CHAR PAPI * PAPI * StringBinding
  797. ) = 0;
  798. unsigned int
  799. InqComTimeout (
  800. );
  801. RPC_STATUS
  802. SetComTimeout (
  803. IN unsigned int Timeout
  804. );
  805. RPC_UUID *
  806. InqPointerAtObjectUuid (
  807. );
  808. unsigned int
  809. InqIfNullObjectUuid (
  810. );
  811. virtual RPC_STATUS
  812. ResolveBinding (
  813. IN PRPC_CLIENT_INTERFACE RpcClientInterface
  814. ) = 0;
  815. RPC_STATUS
  816. InquireEntryName (
  817. IN unsigned long EntryNameSyntax,
  818. OUT RPC_CHAR PAPI * PAPI * EntryName
  819. );
  820. RPC_STATUS
  821. SetEntryName (
  822. IN unsigned long EntryNameSyntax,
  823. IN RPC_CHAR PAPI * EntryName
  824. );
  825. virtual RPC_STATUS
  826. InquireDynamicEndpoint (
  827. OUT RPC_CHAR PAPI * PAPI * DynamicEndpoint
  828. );
  829. virtual RPC_STATUS
  830. BindingReset (
  831. ) = 0;
  832. void PAPI * PAPI *
  833. InquireEpLookupHandle (
  834. );
  835. virtual CLIENT_AUTH_INFO *
  836. InquireAuthInformation (
  837. );
  838. virtual RPC_STATUS
  839. SetAuthInformation (
  840. IN RPC_CHAR PAPI * ServerPrincipalName, OPTIONAL
  841. IN unsigned long AuthenticationLevel,
  842. IN unsigned long AuthenticationService,
  843. IN RPC_AUTH_IDENTITY_HANDLE AuthIdentity, OPTIONAL
  844. IN unsigned long AuthorizationService, OPTIONAL
  845. IN SECURITY_CREDENTIALS PAPI * Credentials = 0, OPTIONAL
  846. IN unsigned long ImpersonationType = RPC_C_IMP_LEVEL_IMPERSONATE,OPTIONAL
  847. IN unsigned long IdentityTracking = RPC_C_QOS_IDENTITY_STATIC, OPTIONAL
  848. IN unsigned long Capabilities = RPC_C_QOS_CAPABILITIES_DEFAULT, OPTIONAL
  849. IN BOOL bAcquireNewCredentials = FALSE, OPTIONAL
  850. IN ULONG AdditionalTransportCredentialsType = 0, OPTIONAL
  851. IN void *AdditionalCredentials = NULL OPTIONAL
  852. );
  853. virtual int
  854. SetServerPrincipalName (
  855. IN RPC_CHAR PAPI *ServerPrincipalName
  856. );
  857. virtual unsigned long
  858. MapAuthenticationLevel (
  859. IN unsigned long AuthenticationLevel
  860. );
  861. virtual BOOL
  862. SetTransportAuthentication(
  863. IN unsigned long ulAuthenticationLevel,
  864. IN unsigned long ulAuthenticationService,
  865. OUT RPC_STATUS *pStatus
  866. );
  867. virtual RPC_STATUS // Value to be returned by SendReceive API.
  868. SendReceive ( // Perform a send-receive operation in a handle specific
  869. // way.
  870. IN OUT PRPC_MESSAGE Message
  871. );
  872. virtual RPC_STATUS
  873. Send (
  874. IN OUT PRPC_MESSAGE Message
  875. ) ;
  876. virtual RPC_STATUS
  877. Receive (
  878. IN OUT PRPC_MESSAGE Message,
  879. IN unsigned int Size
  880. ) ;
  881. virtual RPC_STATUS // Value to be returned by RpcGetBuffer API.
  882. GetBuffer ( // Perform a buffer allocation operation in a handle specific
  883. // way.
  884. IN OUT PRPC_MESSAGE Message,
  885. IN UUID *ObjectUuid
  886. ) = 0;
  887. virtual void
  888. FreeBuffer ( // Perform a buffer deallocation operation in a handle
  889. // specific way.
  890. IN PRPC_MESSAGE Message
  891. );
  892. virtual RPC_STATUS
  893. InquireTransportType(
  894. OUT unsigned int PAPI * Type
  895. ) = 0;
  896. virtual RPC_STATUS
  897. ReAcquireCredentialsIfNecessary(
  898. void
  899. );
  900. virtual RPC_STATUS
  901. SetTransportOption( unsigned long option,
  902. ULONG_PTR optionValue );
  903. virtual RPC_STATUS
  904. InqTransportOption( unsigned long option,
  905. ULONG_PTR * pOptionValue );
  906. };
  907. inline unsigned int
  908. BINDING_HANDLE::InqComTimeout (
  909. )
  910. /*++
  911. Routine Description:
  912. All we have got to do is to return the communications timeout for
  913. this binding handle.
  914. Return Value:
  915. The communications timeout in this binding handle will be returned.
  916. --*/
  917. {
  918. return(Timeout);
  919. }
  920. inline RPC_UUID *
  921. BINDING_HANDLE::InqPointerAtObjectUuid (
  922. )
  923. /*++
  924. Routine Description:
  925. This reader returns a pointer to the object uuid contained in this
  926. binding handle.
  927. Return Value:
  928. A pointer to the object uuid contained in this binding handle is
  929. always returned.
  930. --*/
  931. {
  932. return(&ObjectUuid);
  933. }
  934. inline unsigned int
  935. BINDING_HANDLE::InqIfNullObjectUuid (
  936. )
  937. /*++
  938. Routine Description:
  939. This method is used to inquire if the object uuid in this binding
  940. handle is null or not.
  941. Return Value:
  942. Zero will be returned if object uuid is not null, otherwise (the
  943. object uuid is null) zero will be returned.
  944. --*/
  945. {
  946. return(NullObjectUuidFlag);
  947. }
  948. inline void PAPI * PAPI *
  949. BINDING_HANDLE::InquireEpLookupHandle (
  950. )
  951. /*++
  952. Return Value:
  953. A pointer to the endpoint mapper lookup handle for this binding
  954. handle will be returned.
  955. --*/
  956. {
  957. return(&EpLookupHandle);
  958. }
  959. inline CLIENT_AUTH_INFO *
  960. BINDING_HANDLE::InquireAuthInformation (
  961. )
  962. /*++
  963. Return Value:
  964. If this binding handle is authenticated, then a pointer to its
  965. authentication and authorization information will be returned;
  966. otherwise, zero will be returned.
  967. --*/
  968. {
  969. return(&ClientAuthInfo);
  970. }
  971. ////////////////////////////////////////////////////////////////////
  972. /// Stub interface information
  973. ////////////////////////////////////////////////////////////////////
  974. const int MaximumNumberOfTransferSyntaxes = 2;
  975. const int TransferSyntaxIsServerPreferredFlag = 1;
  976. const int TransferSyntaxListStartFlag = 2;
  977. class TRANSFER_SYNTAX_STUB_INFO
  978. {
  979. public:
  980. RPC_SYNTAX_IDENTIFIER TransferSyntax;
  981. PRPC_DISPATCH_TABLE DispatchTable;
  982. };
  983. class TRANSFER_SYNTAX_INFO_ATOM : public TRANSFER_SYNTAX_STUB_INFO
  984. {
  985. public:
  986. void Init (TRANSFER_SYNTAX_STUB_INFO *TransferSyntaxInfo)
  987. {
  988. Flags = 0;
  989. RpcpMemoryCopy(this, TransferSyntaxInfo, sizeof(TRANSFER_SYNTAX_STUB_INFO));
  990. }
  991. inline BOOL IsTransferSyntaxServerPreferred(void)
  992. {
  993. return (Flags & TransferSyntaxIsServerPreferredFlag);
  994. }
  995. inline void TransferSyntaxIsServerPreferred(void)
  996. {
  997. Flags |= TransferSyntaxIsServerPreferredFlag;
  998. }
  999. inline void TransferSyntaxIsNotServerPreferred(void)
  1000. {
  1001. Flags &= ~TransferSyntaxIsServerPreferredFlag;
  1002. }
  1003. inline BOOL IsTransferSyntaxListStart(void)
  1004. {
  1005. return (Flags & TransferSyntaxListStartFlag);
  1006. }
  1007. inline void TransferSyntaxIsListStart(void)
  1008. {
  1009. Flags |= TransferSyntaxListStartFlag;
  1010. }
  1011. private:
  1012. // can be:
  1013. // TransferSyntaxIsServerPreferredFlag
  1014. // TransferSyntaxListStartFlag
  1015. int Flags;
  1016. };
  1017. // Interface can be both RPC_CLIENT_INTERFACE & RPC_SERVER_INTERFACE
  1018. inline BOOL DoesInterfaceSupportMultipleTransferSyntaxes(void *Interface)
  1019. {
  1020. // the client and server interface have the same layout - we can just
  1021. // use one of them
  1022. RPC_CLIENT_INTERFACE *ClientInterface = (RPC_CLIENT_INTERFACE *)Interface;
  1023. ASSERT ((ClientInterface->Length == sizeof(RPC_CLIENT_INTERFACE))
  1024. || (ClientInterface->Length == NT351_INTERFACE_SIZE));
  1025. ASSERT(sizeof(RPC_CLIENT_INTERFACE) == sizeof(RPC_SERVER_INTERFACE));
  1026. #if !defined(_WIN64)
  1027. if (ClientInterface->Length == NT351_INTERFACE_SIZE)
  1028. return FALSE;
  1029. #else
  1030. ASSERT(ClientInterface->Length == sizeof(RPC_CLIENT_INTERFACE));
  1031. #endif
  1032. return (ClientInterface->Flags & RPCFLG_HAS_MULTI_SYNTAXES);
  1033. }
  1034. // And here we have a couple of inline operators for comparing GUIDs.
  1035. // There is no particular reason that they should live here.
  1036. inline int
  1037. operator == (
  1038. IN GUID& guid1,
  1039. IN GUID& guid2
  1040. ) {return(RpcpMemoryCompare(&guid1,&guid2,sizeof(GUID)) == 0);}
  1041. inline int
  1042. operator == (
  1043. IN GUID PAPI * guid1,
  1044. IN GUID& guid2
  1045. ) {return(RpcpMemoryCompare(guid1,&guid2,sizeof(GUID)) == 0);}
  1046. extern const RPC_SYNTAX_IDENTIFIER *NDR20TransferSyntax;
  1047. extern const RPC_SYNTAX_IDENTIFIER *NDR64TransferSyntax;
  1048. extern const RPC_SYNTAX_IDENTIFIER *NDRTestTransferSyntax;
  1049. extern
  1050. int
  1051. InitializeClientDLL ( // This routine will be called at DLL load time.
  1052. );
  1053. extern int
  1054. InitializeLoadableTransportClient (
  1055. );
  1056. extern int
  1057. InitializeRpcProtocolOfsClient (
  1058. );
  1059. extern int
  1060. InitializeRpcProtocolDgClient (
  1061. );
  1062. START_C_EXTERN
  1063. extern int
  1064. InitializeWinExceptions (
  1065. );
  1066. END_C_EXTERN
  1067. #define DEFAULT_MAX_DATAGRAM_LENGTH (0)
  1068. extern unsigned DefaultMaxDatagramLength;
  1069. #define DEFAULT_CONNECTION_BUFFER_LENGTH (0)
  1070. extern unsigned DefaultConnectionBufferLength;
  1071. typedef struct _RPC_RUNTIME_INFO
  1072. {
  1073. unsigned int Length ;
  1074. unsigned long Flags ;
  1075. void __RPC_FAR *OldBuffer ;
  1076. } RPC_RUNTIME_INFO, __RPC_FAR *PRPC_RUNTIME_INFO ;
  1077. void
  1078. I_RpcAPCRoutine (
  1079. IN RPC_APC_INFO *pAPCInfo
  1080. );
  1081. inline BOOL IsPartialMessage (RPC_MESSAGE *Message)
  1082. {
  1083. return (Message->RpcFlags & RPC_BUFFER_PARTIAL);
  1084. }
  1085. inline BOOL IsExtraMessage (RPC_MESSAGE *Message)
  1086. {
  1087. return (Message->RpcFlags & RPC_BUFFER_EXTRA);
  1088. }
  1089. inline BOOL IsAsyncMessage (RPC_MESSAGE *Message)
  1090. {
  1091. return (Message->RpcFlags & RPC_BUFFER_ASYNC);
  1092. }
  1093. inline BOOL IsCompleteMessage (RPC_MESSAGE *Message)
  1094. {
  1095. return (Message->RpcFlags & RPC_BUFFER_COMPLETE);
  1096. }
  1097. inline BOOL IsNotifyMessage (RPC_MESSAGE *Message)
  1098. {
  1099. return (!(Message->RpcFlags & RPC_BUFFER_NONOTIFY));
  1100. }
  1101. inline BOOL IsNonsyncMessage (RPC_MESSAGE *Message)
  1102. {
  1103. return (Message->RpcFlags & (RPC_BUFFER_ASYNC | RPC_BUFFER_PARTIAL));
  1104. }
  1105. #define PARTIAL(_Message) ((_Message)->RpcFlags & RPC_BUFFER_PARTIAL)
  1106. #define EXTRA(_Message) ((_Message)->RpcFlags & RPC_BUFFER_EXTRA)
  1107. #define ASYNC(_Message) ((_Message)->RpcFlags & RPC_BUFFER_ASYNC)
  1108. #define COMPLETE(_Message) ((_Message)->RpcFlags & RPC_BUFFER_COMPLETE)
  1109. #define NOTIFY(_Message) (!((_Message)->RpcFlags & RPC_BUFFER_NONOTIFY))
  1110. #define NONSYNC(_Message) ((_Message)->RpcFlags & \
  1111. (RPC_BUFFER_ASYNC | RPC_BUFFER_PARTIAL))
  1112. class RPC_SERVER;
  1113. class LRPC_SERVER;
  1114. extern int RpcHasBeenInitialized;
  1115. extern RPC_SERVER * GlobalRpcServer;
  1116. extern BOOL g_fClientSideDebugInfoEnabled;
  1117. extern BOOL g_fServerSideDebugInfoEnabled;
  1118. extern LRPC_SERVER *GlobalLrpcServer;
  1119. extern HINSTANCE hInstanceDLL ;
  1120. inline BOOL IsClientSideDebugInfoEnabled(void)
  1121. {
  1122. return g_fClientSideDebugInfoEnabled;
  1123. }
  1124. inline BOOL IsServerSideDebugInfoEnabled(void)
  1125. {
  1126. return g_fServerSideDebugInfoEnabled;
  1127. }
  1128. #endif // __HANDLE_HXX__