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.

672 lines
18 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation, 1991 - 1999
  3. Module Name:
  4. binding.hxx
  5. Abstract:
  6. The class representing a DCE binding lives here. A DCE binding
  7. consists of an optional object UUID, an RPC protocol sequence, a
  8. network address, an optional endpoint, and zero or more network
  9. options.
  10. Author:
  11. Michael Montague (mikemon) 04-Nov-1991
  12. Revision History:
  13. --*/
  14. #ifndef __BINDING_HXX__
  15. #define __BINDING_HXX__
  16. class BINDING_HANDLE;
  17. class DCE_BINDING
  18. /*++
  19. Class Description:
  20. Instances of this class represent an internalized form of a string
  21. binding. In particular, a string binding can be used to construct
  22. an instance of DCE_BINDING. We parse the string binding into
  23. its components and convert the object UUID from a string to a
  24. UUID.
  25. Fields:
  26. ObjectUuid - Contains the object uuid for this binding. This
  27. field will always contain a valid object uuid. If no object
  28. uuid was specified in the string binding used to create an
  29. instance, then ObjectUuid will be the NULL UUID.
  30. RpcProtocolSequence - Contains the rpc protocol sequence for this
  31. binding. This field will always either point to a string or
  32. be zero.
  33. NetworkAddress - Contains the network addres for this binding. This
  34. field will always be zero or point to a string (which is the
  35. network address for this dce binding).
  36. Endpoint - Contains the endpoint for this binding, which will either
  37. pointer to a string or be zero.
  38. Options - Contains the optional network options for this binding.
  39. As will the other fields, this field will either point to a string,
  40. or be zero.
  41. --*/
  42. {
  43. private:
  44. RPC_CHAR * RpcProtocolSequence;
  45. RPC_CHAR * NetworkAddress;
  46. RPC_CHAR * Endpoint;
  47. RPC_CHAR * Options;
  48. RPC_UUID ObjectUuid;
  49. public:
  50. DCE_BINDING (
  51. IN RPC_CHAR PAPI * ObjectUuid OPTIONAL,
  52. IN RPC_CHAR PAPI * RpcProtocolSequence OPTIONAL,
  53. IN RPC_CHAR PAPI * NetworkAddress OPTIONAL,
  54. IN RPC_CHAR PAPI * Endpoint OPTIONAL,
  55. IN RPC_CHAR PAPI * Options OPTIONAL,
  56. OUT RPC_STATUS PAPI * Status
  57. );
  58. DCE_BINDING (
  59. IN RPC_CHAR PAPI * StringBinding,
  60. OUT RPC_STATUS PAPI * Status
  61. );
  62. ~DCE_BINDING (
  63. );
  64. RPC_CHAR PAPI *
  65. StringBindingCompose (
  66. IN RPC_UUID PAPI * Uuid OPTIONAL,
  67. IN BOOL fStatic = 0
  68. );
  69. RPC_CHAR PAPI *
  70. ObjectUuidCompose (
  71. OUT RPC_STATUS PAPI * Status
  72. );
  73. RPC_CHAR PAPI *
  74. RpcProtocolSequenceCompose (
  75. OUT RPC_STATUS PAPI * Status
  76. );
  77. RPC_CHAR PAPI *
  78. NetworkAddressCompose (
  79. OUT RPC_STATUS PAPI * Status
  80. );
  81. RPC_CHAR PAPI *
  82. EndpointCompose (
  83. OUT RPC_STATUS PAPI * Status
  84. );
  85. RPC_CHAR PAPI *
  86. OptionsCompose (
  87. OUT RPC_STATUS PAPI * Status
  88. );
  89. BINDING_HANDLE *
  90. CreateBindingHandle (
  91. OUT RPC_STATUS PAPI * Status
  92. );
  93. RPC_CHAR *
  94. InqNetworkAddress (
  95. );
  96. RPC_CHAR *
  97. InqEndpoint (
  98. );
  99. BOOL
  100. IsNullEndpoint (
  101. void
  102. );
  103. RPC_CHAR *
  104. InqNetworkOptions (
  105. );
  106. RPC_CHAR *
  107. InqRpcProtocolSequence (
  108. );
  109. void
  110. AddEndpoint(
  111. IN RPC_CHAR *Endpoint
  112. );
  113. RPC_STATUS
  114. ResolveEndpointIfNecessary (
  115. IN PRPC_CLIENT_INTERFACE RpcInterfaceInformation,
  116. IN RPC_UUID * ObjectUuid,
  117. IN OUT void PAPI * PAPI * EpLookupHandle,
  118. IN BOOL UseEpMapperEp,
  119. IN unsigned ConnTimeout,
  120. IN ULONG CallTimeout,
  121. IN CLIENT_AUTH_INFO *AuthInfo OPTIONAL
  122. );
  123. int
  124. Compare (
  125. IN DCE_BINDING * DceBinding,
  126. OUT BOOL *fOnlyEndpointDiffers
  127. );
  128. int
  129. CompareWithoutSecurityOptions (
  130. IN DCE_BINDING * DceBinding,
  131. OUT BOOL *fOnlyEndpointDiffers
  132. );
  133. DCE_BINDING *
  134. DuplicateDceBinding (
  135. );
  136. void
  137. MakePartiallyBound (
  138. );
  139. BOOL
  140. MaybeMakePartiallyBound (
  141. IN PRPC_CLIENT_INTERFACE RpcInterfaceInformation,
  142. IN RPC_UUID * ObjectUuid
  143. );
  144. BOOL
  145. IsNamedPipeTransport (
  146. )
  147. {
  148. return (RpcpStringCompare(RpcProtocolSequence, RPC_CONST_STRING("ncacn_np")) == 0);
  149. }
  150. inline BOOL
  151. IsNullObjectUuid (
  152. void
  153. )
  154. {
  155. return ObjectUuid.IsNullUuid();
  156. }
  157. };
  158. inline RPC_CHAR *
  159. DCE_BINDING::InqNetworkAddress (
  160. )
  161. /*++
  162. Routine Description:
  163. A pointer to the network address for this address is returned.
  164. --*/
  165. {
  166. return(NetworkAddress);
  167. }
  168. inline RPC_CHAR *
  169. DCE_BINDING::InqEndpoint (
  170. )
  171. /*++
  172. Routine Description:
  173. A pointer to the endpoint for this address is returned.
  174. --*/
  175. {
  176. return(Endpoint);
  177. }
  178. inline BOOL
  179. DCE_BINDING::IsNullEndpoint (
  180. void
  181. )
  182. /*++
  183. Routine Description:
  184. Returns non-zero if the endpoint
  185. is NULL.
  186. --*/
  187. {
  188. return ((Endpoint == NULL) || (Endpoint[0] == 0));
  189. }
  190. inline RPC_CHAR *
  191. DCE_BINDING::InqNetworkOptions (
  192. )
  193. /*++
  194. Routine Description:
  195. A pointer to the network options for this address is returned.
  196. --*/
  197. {
  198. return(Options);
  199. }
  200. inline RPC_CHAR *
  201. DCE_BINDING::InqRpcProtocolSequence (
  202. )
  203. /*++
  204. Routine Description:
  205. A pointer to the rpc protocol sequence for this binding is returned.
  206. --*/
  207. {
  208. return(RpcProtocolSequence);
  209. }
  210. #define MAX_PROTSEQ_LENGTH MAX_DLLNAME_LENGTH
  211. class LOADABLE_TRANSPORT;
  212. class TRANS_INFO
  213. /*++
  214. Class Description:
  215. Fields:
  216. pTransportInterface - Contains all of the required information about
  217. a loadable transport so that we can make use of it.
  218. --*/
  219. {
  220. private:
  221. RPC_TRANSPORT_INTERFACE pTransportInterface;
  222. LOADABLE_TRANSPORT *LoadableTrans ;
  223. RPC_CHAR RpcProtocolSequence[MAX_PROTSEQ_LENGTH + 1];
  224. public:
  225. TRANS_INFO (
  226. IN RPC_TRANSPORT_INTERFACE pTransportInterface,
  227. IN RPC_CHAR *ProtocolSeq,
  228. IN LOADABLE_TRANSPORT *LoadableTrans
  229. ) ;
  230. BOOL
  231. MatchProtseq(
  232. IN RPC_CHAR *ProtocolSeq
  233. ) ;
  234. BOOL
  235. MatchId (
  236. IN unsigned short Id
  237. );
  238. RPC_TRANSPORT_INTERFACE
  239. InqTransInfo (
  240. );
  241. RPC_STATUS
  242. StartServerIfNecessary(
  243. );
  244. RPC_STATUS
  245. CreateThread (
  246. );
  247. };
  248. inline
  249. TRANS_INFO::TRANS_INFO (
  250. IN RPC_TRANSPORT_INTERFACE pTransportInterface,
  251. IN RPC_CHAR *ProtocolSeq,
  252. IN LOADABLE_TRANSPORT *LoadableTrans
  253. )
  254. {
  255. this->pTransportInterface = pTransportInterface ;
  256. RpcpStringCopy(RpcProtocolSequence, ProtocolSeq) ;
  257. this->LoadableTrans = LoadableTrans ;
  258. }
  259. inline BOOL
  260. TRANS_INFO::MatchProtseq(
  261. IN RPC_CHAR *ProtocolSeq
  262. )
  263. {
  264. if (RpcpStringCompare(ProtocolSeq, RpcProtocolSequence) == 0)
  265. {
  266. return 1 ;
  267. }
  268. return 0;
  269. }
  270. inline BOOL
  271. TRANS_INFO::MatchId (
  272. IN unsigned short Id
  273. )
  274. {
  275. if (pTransportInterface->TransId == Id)
  276. {
  277. return 1;
  278. }
  279. return 0;
  280. }
  281. inline RPC_TRANSPORT_INTERFACE
  282. TRANS_INFO::InqTransInfo (
  283. )
  284. {
  285. return pTransportInterface ;
  286. }
  287. NEW_SDICT (TRANS_INFO);
  288. class LOADABLE_TRANSPORT
  289. /*++
  290. Class Description:
  291. This class is used as an item in a dictionary of loaded loadable
  292. transports. It contains the information we are interested in,
  293. the RPC_TRANSPORT_INTERFACE, as well as the name of the dll we loaded
  294. the transport interface from. The dll name is the key to the
  295. dictionary.
  296. Fields:
  297. DllName - Contains the name of the dll from which we loaded
  298. this transport interface.
  299. LoadedDll - Contains the dll which we had to load to get the transport
  300. support. We need to save this information so that under Windows
  301. when the runtime is unloaded, we can unload all of the transports.
  302. --*/
  303. {
  304. private:
  305. // accessed by all threads independently - put in separate cache line
  306. LONG ThreadsStarted ;
  307. RPC_CHAR DllName[MAX_DLLNAME_LENGTH + 1];
  308. // accessed by all threads independently - put in separate cache line
  309. // NumThreads is the number of threads actually doing a listen on the
  310. // completion port - this excludes the ones that are doing processing
  311. LONG NumThreads;
  312. DLL * LoadedDll;
  313. TRANS_INFO_DICT ProtseqDict ;
  314. // accessed by all threads independently - put in a separate cache line
  315. // ThreadsDoingLongWait is the number of threads that are waiting on
  316. // the completion port and their wait timeout is > MAX_SHORT_THREAD_TIMEOUT
  317. // In other words, those threads are not guaranteed to check for
  318. // garbage collection before gThreadTimeout
  319. INTERLOCKED_INTEGER ThreadsDoingLongWait;
  320. LONG Reserved0[7];
  321. // read-only often used section
  322. PROCESS_CALLS ProcessCallsFunc;
  323. long nOptimalNumberOfThreads;
  324. #ifndef NO_PLUG_AND_PLAY
  325. LISTEN_FOR_PNP_NOTIFICATIONS PnpListen;
  326. friend void ProcessNewAddressEvent(LOADABLE_TRANSPORT *pLoadableTransport,
  327. IN RPC_TRANSPORT_EVENT Event,
  328. IN RPC_STATUS EventStatus,
  329. IN PVOID pEventContext,
  330. IN UINT BufferLength,
  331. IN BUFFER Buffer,
  332. IN PVOID pSourceContext);
  333. #endif
  334. FuncGetHandleForThread GetHandleForThread;
  335. FuncReleaseHandleForThread ReleaseHandleForThread;
  336. LONG Reserved1[3];
  337. // accessed by all threads independently - put in separate cache line
  338. LONG Reserved2[7];
  339. // the total number of worker threads on the completion port - this
  340. // includes the ones that are listening, and the one that have picked
  341. // up work items and are working on them.
  342. INTERLOCKED_INTEGER nThreadsAtCompletionPort;
  343. // accessed by all threads independently - put in separate cache line
  344. LONG Reserved3[7];
  345. int nActivityValue;
  346. public:
  347. LOADABLE_TRANSPORT (
  348. IN RPC_TRANSPORT_INTERFACE pTransportInterface,
  349. IN RPC_CHAR * DllName,
  350. IN RPC_CHAR PAPI * ProtocolSequence,
  351. IN DLL *LoadableTransportDll,
  352. IN FuncGetHandleForThread GetHandleForThread,
  353. IN FuncReleaseHandleForThread ReleaseHandleForThread,
  354. OUT RPC_STATUS *Status,
  355. OUT TRANS_INFO * PAPI *TransInfo
  356. );
  357. TRANS_INFO *
  358. MapProtocol (
  359. IN RPC_CHAR * DllName,
  360. IN RPC_CHAR PAPI * ProtocolSequence
  361. );
  362. TRANS_INFO *
  363. MatchId (
  364. IN unsigned short Id
  365. );
  366. void
  367. ProcessIOEvents (
  368. );
  369. RPC_STATUS
  370. StartServerIfNecessary (
  371. );
  372. RPC_STATUS
  373. ProcessCalls (
  374. IN INT Timeout,
  375. OUT RPC_TRANSPORT_EVENT *pEvent,
  376. OUT RPC_STATUS *pEventStatus,
  377. OUT PVOID *ppEventContext,
  378. OUT UINT *pBufferLength,
  379. OUT BUFFER *pBuffer,
  380. OUT PVOID *ppSourceContext);
  381. RPC_STATUS CreateThread (void);
  382. // N.B. This can return negative numbers in rare race
  383. // conditions - make sure you handle it
  384. inline long GetThreadsDoingShortWait (
  385. void
  386. )
  387. {
  388. return (NumThreads - ThreadsDoingLongWait.GetInteger());
  389. }
  390. };
  391. inline
  392. RPC_STATUS
  393. TRANS_INFO::StartServerIfNecessary (
  394. )
  395. {
  396. return LoadableTrans->StartServerIfNecessary() ;
  397. }
  398. inline RPC_STATUS
  399. TRANS_INFO::CreateThread (
  400. )
  401. {
  402. return LoadableTrans->CreateThread();
  403. }
  404. NEW_SDICT(LOADABLE_TRANSPORT);
  405. extern LOADABLE_TRANSPORT_DICT * LoadedLoadableTransports;
  406. RPC_STATUS
  407. LoadableTransportInfo (
  408. IN RPC_CHAR * DllName,
  409. IN RPC_CHAR PAPI * RpcProtocolSequence,
  410. OUT TRANS_INFO * PAPI *pTransInfo
  411. );
  412. extern BOOL GetTransportEntryPoints(IN DLL *LoadableTransportDll,
  413. OUT TRANSPORT_LOAD *TransportLoad,
  414. OUT FuncGetHandleForThread *GetHandleForThread,
  415. OUT FuncReleaseHandleForThread *ReleaseHandleForThread
  416. );
  417. extern void
  418. UnjoinCompletionPort (
  419. void
  420. );
  421. extern RPC_STATUS
  422. IsRpcProtocolSequenceSupported (
  423. IN RPC_CHAR PAPI * RpcProtocolSequence
  424. );
  425. RPC_STATUS
  426. OsfMapRpcProtocolSequence (
  427. IN BOOL ServerSideFlag,
  428. IN RPC_CHAR PAPI * RpcProtocolSequence,
  429. OUT TRANS_INFO * PAPI *ClientTransInfo
  430. ) ;
  431. extern BINDING_HANDLE *
  432. OsfCreateBindingHandle (
  433. );
  434. extern BINDING_HANDLE *
  435. LrpcCreateBindingHandle (
  436. );
  437. extern BINDING_HANDLE *
  438. DgCreateBindingHandle (
  439. void
  440. );
  441. extern RPC_CHAR *
  442. AllocateEmptyString (
  443. void
  444. );
  445. #define DuplicateStringPAPI DuplicateString
  446. #define AllocateEmptyStringPAPI AllocateEmptyString
  447. #define DG_EVENT_CALLBACK_COMPLETE 0x9991
  448. #define CO_EVENT_BIND_TO_SERVER 0x9992
  449. // don't use 9993 - it's already used
  450. #define IN_PROXY_IIS_DIRECT_RECV 0x9994
  451. #define HTTP2_DIRECT_RECEIVE 0x9995
  452. #define PLUG_CHANNEL_DIRECT_SEND 0x9996
  453. #define CHANNEL_DATA_ORIGINATOR_DIRECT_SEND 0x9997
  454. #define HTTP2_RESCHEDULE_TIMER 0x9998
  455. #define HTTP2_FLOW_CONTROL_DIRECT_SEND 0x9999
  456. #define HTTP2_WINHTTP_DIRECT_RECV 0x999A
  457. #define HTTP2_WINHTTP_DIRECT_SEND 0x999B
  458. #define HTTP2_ABORT_CONNECTION 0x999C
  459. #define HTTP2_RECYCLE_CHANNEL 0x999D
  460. #define HTTP2_WINHTTP_DELAYED_RECV 0x999E
  461. extern UUID MgmtIf;
  462. extern UUID NullUuid;
  463. //
  464. // The declarations need to be placed here so that loader.cxx can overwirte the
  465. // dafult IO event handlers when running with rpc verifier and corruption injection.
  466. //
  467. typedef void ProcessIOEventFunc(LOADABLE_TRANSPORT *pLoadableTransport,
  468. IN RPC_TRANSPORT_EVENT Event,
  469. IN RPC_STATUS EventStatus,
  470. IN PVOID pEventContext,
  471. IN UINT BufferLength,
  472. IN BUFFER Buffer,
  473. IN PVOID pSourceContext);
  474. extern ProcessIOEventFunc *IOEventDispatchTable[];
  475. extern void ProcessConnectionServerReceivedEventAvrf(LOADABLE_TRANSPORT *pLoadableTransport,
  476. IN RPC_TRANSPORT_EVENT Event,
  477. IN RPC_STATUS EventStatus,
  478. IN PVOID pEventContext,
  479. IN UINT BufferLength,
  480. IN BUFFER Buffer,
  481. IN PVOID pSourceContext);
  482. extern void ProcessConnectionClientReceiveEventAvrf(LOADABLE_TRANSPORT *pLoadableTransport,
  483. IN RPC_TRANSPORT_EVENT Event,
  484. IN RPC_STATUS EventStatus,
  485. IN PVOID pEventContext,
  486. IN UINT BufferLength,
  487. IN BUFFER Buffer,
  488. IN PVOID pSourceContext);
  489. extern void ProcessDatagramServerReceiveEventAvrf(LOADABLE_TRANSPORT *pLoadableTransport,
  490. IN RPC_TRANSPORT_EVENT Event,
  491. IN RPC_STATUS EventStatus,
  492. IN PVOID pEventContext,
  493. IN UINT BufferLength,
  494. IN BUFFER Buffer,
  495. IN PVOID pSourceContext);
  496. extern void ProcessDatagramClientReceiveEventAvrf(LOADABLE_TRANSPORT *pLoadableTransport,
  497. IN RPC_TRANSPORT_EVENT Event,
  498. IN RPC_STATUS EventStatus,
  499. IN PVOID pEventContext,
  500. IN UINT BufferLength,
  501. IN BUFFER Buffer,
  502. IN PVOID pSourceContext);
  503. extern void ProcessComplexTReceiveAvrf(LOADABLE_TRANSPORT *pLoadableTransport,
  504. IN RPC_TRANSPORT_EVENT Event,
  505. IN RPC_STATUS EventStatus,
  506. IN PVOID pEventContext,
  507. IN UINT BufferLength,
  508. IN BUFFER Buffer,
  509. IN PVOID pSourceContext);
  510. BOOL
  511. ProcessIOEventsWrapper(
  512. IN LOADABLE_TRANSPORT *Transport
  513. ) ;
  514. void
  515. ProcessDgClientPacket(
  516. IN DWORD Status,
  517. IN DG_TRANSPORT_ENDPOINT LocalEndpoint,
  518. IN void * PacketHeader,
  519. IN unsigned long PacketLength,
  520. IN DatagramTransportPair *AddressPair
  521. );
  522. void
  523. ProcessDgServerPacket(
  524. IN DWORD Status,
  525. IN DG_TRANSPORT_ENDPOINT LocalEndpoint,
  526. IN void * PacketHeader,
  527. IN unsigned long PacketLength,
  528. IN DatagramTransportPair *AddressPair
  529. );
  530. #endif // __BINDING_HXX__