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.

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