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.

881 lines
22 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation, 1991 - 1999
  3. Module Name:
  4. epclnt.cxx
  5. Abstract:
  6. This file contains the client runtime entry points into the
  7. endpoint mapper dll.
  8. Author:
  9. Michael Montague (mikemon) 06-Jan-1992
  10. Revision History:
  11. --*/
  12. #include <precomp.hxx>
  13. #include <epmp.h>
  14. #include <epmap.h>
  15. #include <twrproto.h>
  16. #include <CharConv.hxx>
  17. #include <OsfPcket.hxx>
  18. #include <BitSet.hxx>
  19. #include <ProtBind.hxx>
  20. #include <OsfClnt.hxx>
  21. extern RPC_STATUS __RPC_FAR
  22. MapFromNcaStatusCode (
  23. IN unsigned long NcaStatus
  24. );
  25. static ProtseqEndpointPair EpMapperTable[] =
  26. {
  27. "ncacn_np", "\\pipe\\epmapper",
  28. "ncalrpc", "epmapper",
  29. "ncacn_ip_tcp", "135",
  30. "ncadg_ip_udp", "135",
  31. #ifdef NETBIOS_ON
  32. "ncacn_nb_nb", "135",
  33. "ncacn_nb_tcp", "135",
  34. "ncacn_nb_ipx", "135",
  35. #endif
  36. #ifdef SPX_ON
  37. "ncacn_spx", "34280",
  38. #endif
  39. #ifdef IPX_ON
  40. "ncadg_ipx", "34280",
  41. #endif
  42. #ifdef APPLETALK_ON
  43. "ncacn_at_dsp", "Endpoint Mapper",
  44. #endif
  45. #ifdef NCADG_MQ_ON
  46. "ncadg_mq", "EpMapper",
  47. #endif
  48. "ncacn_http", "593"
  49. };
  50. unsigned long PartialRetries=0;
  51. unsigned long ReallyTooBusy=0;
  52. typedef struct _EP_LOOKUP_DATA
  53. {
  54. unsigned int NumberOfEndpoints;
  55. unsigned int MaximumEndpoints;
  56. unsigned int CurrentEndpoint;
  57. RPC_CHAR * PAPI * Endpoints;
  58. } EP_LOOKUP_DATA;
  59. RPC_STATUS RPC_ENTRY
  60. EpResolveEndpoint (
  61. IN UUID PAPI * ObjectUuid, OPTIONAL
  62. IN RPC_SYNTAX_IDENTIFIER PAPI * IfId,
  63. IN RPC_SYNTAX_IDENTIFIER PAPI * XferId,
  64. IN RPC_CHAR PAPI * RpcProtocolSequence,
  65. IN RPC_CHAR PAPI * NetworkAddress,
  66. IN RPC_CHAR PAPI * Options,
  67. IN OUT void PAPI * PAPI * EpLookupHandle,
  68. IN unsigned ConnTimeout,
  69. IN ULONG CallTimeout,
  70. IN CLIENT_AUTH_INFO *AuthInfo, OPTIONAL
  71. OUT RPC_CHAR * PAPI * Endpoint
  72. )
  73. /*++
  74. Routine Description:
  75. The runtime will call this routine to resolve an endpoint.
  76. Arguments:
  77. ObjectUuid - Optional specifies the object uuid in the binding
  78. for which we are trying to resolve an endpoint.
  79. Ifid - Pointer to the Syntax Identifier for the Interface
  80. Xferid - Pointer to the Syntax Identifier for the Transfer Syntax.
  81. RpcProtocolSequence - Supplies the rpc protocol sequence contained
  82. in the binding.
  83. NetworkAddress - Supplies the network address. This will be used
  84. to contact the endpoint mapper on that machine in order to
  85. resolve the endpoint.
  86. EpLookupHandle - Supplies the current version of the lookup handle
  87. for this iteration through the endpoint mapper. A new value
  88. for the lookup handle will be returned. If RPC_S_NO_ENDPOINT_FOUND
  89. is returned, this parameter will be set to its initial value,
  90. zero.
  91. ConnTimeout - the connection timeout
  92. CallTimeout - the call timeout
  93. AutInfo - any auth info that needs to be used during the resolution process
  94. Endpoint - Returns the endpoint resolved by the endpoint mapper on
  95. the machine specified by the network address argument. The
  96. storage for the endpoint must have been allocated using the
  97. runtime API I_RpcAllocate.
  98. Return Value:
  99. RPC_S_OK - The endpoint was successfully resolved.
  100. EP_S_NOT_REGISTERED - There are no more endpoints to be found
  101. for the specified combination of interface, network address,
  102. and lookup handle.
  103. RPC_S_OUT_OF_MEMORY - Insufficient memory is available to allow
  104. resolution of the endpoint.
  105. EP_S_CANT_PERFORM_OP - The operation failed due to misc. error e.g.
  106. unable to bind to the EpMapper.
  107. --*/
  108. {
  109. RPC_BINDING_HANDLE MapperHandle;
  110. RPC_STATUS RpcStatus;
  111. twr_p_t InputTower = 0;
  112. twr_p_t OutputTower[4];
  113. unsigned long Returned;
  114. error_status ErrorStatus;
  115. ept_lookup_handle_t ContextHandle = 0;
  116. EP_LOOKUP_DATA PAPI * EpLookupData = (EP_LOOKUP_DATA PAPI *)
  117. *EpLookupHandle;
  118. unsigned long RetryCount, i;
  119. unsigned char PAPI * EPoint;
  120. CHeapAnsi AnsiNWAddr, AnsiOptions;
  121. CStackAnsi AnsiProtseq;
  122. CNlUnicode nlEndpoint;
  123. ASSERT(*Endpoint == 0);
  124. // We have already taken all of the endpoints from the endpoint mapper;
  125. // now we just return them back to the runtime one at a time.
  126. ReturnEndpointFromList:
  127. if ( EpLookupData != 0 )
  128. {
  129. // When we reach the end of the list of endpoints, return an error,
  130. // and set things up so that we will start at the beginning again.
  131. if ( EpLookupData->CurrentEndpoint == EpLookupData->NumberOfEndpoints )
  132. {
  133. RpcpErrorAddRecord(EEInfoGCRuntime,
  134. EPT_S_NOT_REGISTERED,
  135. EEInfoDLEpResolveEndpoint10,
  136. RpcProtocolSequence,
  137. NetworkAddress,
  138. IfId->SyntaxGUID.Data1,
  139. (ULONG)((EpLookupData->CurrentEndpoint << 16) | EpLookupData->NumberOfEndpoints));
  140. EpLookupData->CurrentEndpoint = 0;
  141. return(EPT_S_NOT_REGISTERED);
  142. }
  143. *Endpoint = DuplicateString(
  144. EpLookupData->Endpoints[EpLookupData->CurrentEndpoint]);
  145. EpLookupData->CurrentEndpoint += 1;
  146. if ( *Endpoint == 0 )
  147. {
  148. return(RPC_S_OUT_OF_MEMORY);
  149. }
  150. return(RPC_S_OK);
  151. }
  152. // Otherwise, we need to take the list of endpoints from the endpoint
  153. // mapper.
  154. EpLookupData = (EP_LOOKUP_DATA PAPI *) RpcpFarAllocate(
  155. sizeof(EP_LOOKUP_DATA));
  156. if ( EpLookupData == 0 )
  157. {
  158. return(RPC_S_OUT_OF_MEMORY);
  159. }
  160. EpLookupData->MaximumEndpoints = 64;
  161. EpLookupData->Endpoints = (RPC_CHAR * PAPI *) RpcpFarAllocate(
  162. sizeof(RPC_CHAR PAPI *) * EpLookupData->MaximumEndpoints);
  163. if ( EpLookupData->Endpoints == 0 )
  164. {
  165. RpcpFarFree(EpLookupData);
  166. EpLookupData = 0;
  167. return(RPC_S_OUT_OF_MEMORY);
  168. }
  169. EpLookupData->NumberOfEndpoints = 0;
  170. EpLookupData->CurrentEndpoint = 0;
  171. RpcStatus = AnsiNWAddr.Attach(NetworkAddress);
  172. if ( RpcStatus != RPC_S_OK )
  173. {
  174. ASSERT( RpcStatus == RPC_S_OUT_OF_MEMORY );
  175. RpcpFarFree(EpLookupData);
  176. EpLookupData = 0;
  177. return(RpcStatus);
  178. }
  179. i = 1+RpcpStringLength(RpcProtocolSequence);
  180. *(AnsiProtseq.GetPAnsiString()) = (char *)_alloca(i);
  181. RpcStatus = AnsiProtseq.Attach(RpcProtocolSequence, i, i * 2);
  182. if ( RpcStatus != RPC_S_OK )
  183. {
  184. ASSERT( RpcStatus == RPC_S_OUT_OF_MEMORY );
  185. RpcpFarFree(EpLookupData);
  186. EpLookupData = 0;
  187. return(RpcStatus);
  188. }
  189. RpcStatus = AnsiOptions.Attach(Options);
  190. if ( RpcStatus != RPC_S_OK )
  191. {
  192. ASSERT( RpcStatus == RPC_S_OUT_OF_MEMORY );
  193. RpcpFarFree(EpLookupData);
  194. EpLookupData = 0;
  195. return(RpcStatus);
  196. }
  197. RpcStatus = BindToEpMapper(&MapperHandle,
  198. NetworkAddress,
  199. RpcProtocolSequence,
  200. Options,
  201. ConnTimeout,
  202. CallTimeout,
  203. AuthInfo
  204. );
  205. if ( RpcStatus != RPC_S_OK )
  206. {
  207. MapperHandle = 0;
  208. goto CleanupAndReturn;
  209. }
  210. RpcStatus = TowerConstruct((RPC_IF_ID PAPI *) IfId,
  211. (RPC_TRANSFER_SYNTAX PAPI *) XferId, (char PAPI *) AnsiProtseq,
  212. NULL, (char PAPI *) AnsiNWAddr, &InputTower);
  213. if ( RpcStatus != RPC_S_OK )
  214. {
  215. goto CleanupAndReturn;
  216. }
  217. for (RetryCount = 0;;)
  218. {
  219. OutputTower[0] = 0;
  220. OutputTower[1] = 0;
  221. OutputTower[2] = 0;
  222. OutputTower[3] = 0;
  223. RpcTryExcept
  224. {
  225. ept_map(MapperHandle, ObjectUuid, InputTower, &ContextHandle, 4L,
  226. &Returned, &OutputTower[0], &ErrorStatus);
  227. }
  228. RpcExcept(I_RpcExceptionFilter(RpcExceptionCode()))
  229. {
  230. ErrorStatus = RpcExceptionCode();
  231. }
  232. RpcEndExcept
  233. if ( ErrorStatus == RPC_S_SERVER_TOO_BUSY)
  234. {
  235. if (RetryCount < 3)
  236. {
  237. RetryCount ++;
  238. PartialRetries++;
  239. continue;
  240. }
  241. else
  242. {
  243. ReallyTooBusy++;
  244. }
  245. }
  246. if ( ErrorStatus != 0 )
  247. {
  248. // For DCE interop the endpoint mapper returns DCE errors on the
  249. // wire. We need to map some of them to the MS RPC ones.
  250. switch (ErrorStatus)
  251. {
  252. case EP_S_CANT_PERFORM_OP :
  253. RpcStatus = EPT_S_CANT_PERFORM_OP;
  254. break;
  255. case EP_S_NOT_REGISTERED :
  256. RpcpErrorAddRecord(EEInfoGCRuntime,
  257. EPT_S_NOT_REGISTERED,
  258. EEInfoDLEpResolveEndpoint20,
  259. RpcProtocolSequence,
  260. NetworkAddress,
  261. IfId->SyntaxGUID.Data1,
  262. (ULONGLONG)MapperHandle);
  263. RpcStatus = EPT_S_NOT_REGISTERED;
  264. break;
  265. default :
  266. RpcStatus = MapFromNcaStatusCode(ErrorStatus);
  267. break;
  268. }
  269. break;
  270. }
  271. ASSERT( ((Returned != 0) || (ContextHandle == 0)) && (Returned <= 4) );
  272. for (i = 0; i < Returned; i++)
  273. {
  274. if (OutputTower[i] == 0)
  275. {
  276. return RPC_S_OUT_OF_MEMORY ;
  277. }
  278. RpcStatus = TowerExplode(
  279. OutputTower[i],
  280. NULL,
  281. NULL,
  282. NULL,
  283. (char PAPI * PAPI *) &EPoint,
  284. NULL
  285. );
  286. if ( RpcStatus != RPC_S_OK )
  287. {
  288. break;
  289. }
  290. RpcStatus = nlEndpoint.Attach((char *)EPoint);
  291. *Endpoint = nlEndpoint;
  292. I_RpcFree(EPoint);
  293. if ( *Endpoint == 0 )
  294. {
  295. RpcStatus = RPC_S_OUT_OF_MEMORY;
  296. break;
  297. }
  298. EpLookupData->Endpoints[EpLookupData->NumberOfEndpoints] =
  299. *Endpoint;
  300. EpLookupData->NumberOfEndpoints += 1;
  301. if ( EpLookupData->NumberOfEndpoints ==
  302. EpLookupData->MaximumEndpoints )
  303. {
  304. goto OutsideTheLoop;
  305. }
  306. }//..for Loop over parse all towers/eps in this loop
  307. for (i = 0; i < Returned; i++)
  308. {
  309. MIDL_user_free(OutputTower[i]);
  310. }
  311. if ( (ContextHandle == 0) || (RpcStatus != RPC_S_OK) )
  312. {
  313. break;
  314. }
  315. } //..for loop over get all endpoints
  316. OutsideTheLoop:
  317. ASSERT( InputTower != 0 );
  318. I_RpcFree(InputTower);
  319. CleanupAndReturn:
  320. if ( MapperHandle != 0 )
  321. {
  322. RPC_STATUS Status = RpcBindingFree(&MapperHandle);
  323. ASSERT( Status == RPC_S_OK );
  324. }
  325. if ( ContextHandle != 0 )
  326. {
  327. RpcSsDestroyClientContext(&ContextHandle);
  328. }
  329. if ( ( RpcStatus == EPT_S_NOT_REGISTERED )
  330. || ( RpcStatus == RPC_S_OK ) )
  331. {
  332. if ( EpLookupData->NumberOfEndpoints != 0 )
  333. {
  334. *EpLookupHandle = EpLookupData;
  335. goto ReturnEndpointFromList;
  336. }
  337. RpcStatus = EPT_S_NOT_REGISTERED;
  338. }
  339. if ( EpLookupData != 0 )
  340. {
  341. if ( EpLookupData->Endpoints != 0 )
  342. {
  343. while ( EpLookupData->NumberOfEndpoints > 0 )
  344. {
  345. EpLookupData->NumberOfEndpoints -= 1;
  346. delete EpLookupData->Endpoints[EpLookupData->NumberOfEndpoints];
  347. }
  348. RpcpFarFree(EpLookupData->Endpoints);
  349. }
  350. RpcpFarFree(EpLookupData);
  351. }
  352. return(RpcStatus);
  353. }
  354. RPC_STATUS RPC_ENTRY
  355. EpGetEpmapperEndpoint(
  356. IN OUT RPC_CHAR * PAPI * Endpoint,
  357. IN RPC_CHAR PAPI * Protseq
  358. )
  359. /*+
  360. Routine Description:
  361. Returns the Endpoint mappers well known endpoint for a given
  362. protocol sequence.
  363. Arguments:
  364. Endpoint - Place to store the epmappers well known endpoint.
  365. Protsq - Protocol sequence the client wishes to use.
  366. Return Value:
  367. RPC_S_OK - Found the protocol sequence in the epmapper table and
  368. am returning the associated well known endpoint.
  369. EPT_S_CANT_PERFORM_OP - Protocol sequence not found.
  370. --*/
  371. {
  372. RPC_STATUS Status = EPT_S_CANT_PERFORM_OP;
  373. RPC_STATUS rc;
  374. unsigned int i, Count;
  375. CStackAnsi AnsiProtseq;
  376. CNlUnicode nlEndpoint;
  377. unsigned char PAPI * Epoint;
  378. if (Protseq != NULL)
  379. {
  380. #ifdef UNICODE
  381. //Must convert the protocol sequence into an ansi string from unicode
  382. i = 1 + RpcpStringLength(Protseq);
  383. *(AnsiProtseq.GetPAnsiString()) = (char *)_alloca(i);
  384. rc = AnsiProtseq.Attach(Protseq, i, i * 2);
  385. if ( rc != RPC_S_OK )
  386. {
  387. ASSERT( rc == RPC_S_OUT_OF_MEMORY );
  388. return(Status);
  389. }
  390. #else
  391. AnsiProtseq = Protseq;
  392. #endif
  393. Count = sizeof(EpMapperTable)/sizeof(EpMapperTable[0]);
  394. for (i = 0; i < Count; i++)
  395. {
  396. //Search for the protocol sequence client is using.
  397. if ( RpcpStringCompareA((char PAPI *)AnsiProtseq,
  398. (char PAPI *)EpMapperTable[i].Protseq) )
  399. {
  400. //Not yet found.
  401. continue;
  402. }
  403. else
  404. {
  405. //Found a match. Grab the epmappers known endpoint.
  406. Epoint = (unsigned char __RPC_FAR *)(EpMapperTable[i].Endpoint);
  407. rc = nlEndpoint.Attach((char *)Epoint);
  408. *Endpoint = nlEndpoint;
  409. Status = RPC_S_OK;
  410. break;
  411. }
  412. } //for
  413. }//if
  414. return(Status);
  415. }
  416. RPC_STATUS RPC_ENTRY
  417. BindToEpMapper(
  418. OUT RPC_BINDING_HANDLE PAPI * MapperHandle,
  419. IN RPC_CHAR * NWAddress OPTIONAL,
  420. IN RPC_CHAR * Protseq OPTIONAL,
  421. IN RPC_CHAR * Options OPTIONAL,
  422. IN unsigned ConnTimeout,
  423. IN ULONG CallTimeout,
  424. IN CLIENT_AUTH_INFO *AuthInfo OPTIONAL
  425. )
  426. /*+
  427. Routine Description:
  428. This helper routine is used to by RpcEpRegister[NoReplace],
  429. RpcEpUnRegister and EpResolveEndpoint(epclnt.cxx) to bind to
  430. the EpMapper. If a Protseq is supplied, that particular protseq
  431. is tried, otherwise lrpc is used to connect to the local epmapper.
  432. If a NW Address is specified EpMapper at that host is contacted, else
  433. local Endpoint mapper is used.
  434. Arguments:
  435. MapperHandle- Returns binding handle to the Endpoint mapper
  436. NWAddress - NW address of the Endpoint mapper to bind to.
  437. Ignored if protseq is NULL.
  438. Protseq - Protocol sequence the client wishes to use.
  439. NULL indicates a call to the local endpoint mapper.
  440. ConnTimeout - the connection timeout
  441. CallTimeout - the call timeout
  442. AuthInfo - authentication information for the resolution
  443. Return Value:
  444. RPC_S_OK - The ansi string was successfully converted into a unicode
  445. string.
  446. RPC_S_OUT_OF_MEMORY - Insufficient memory is available for the unicode
  447. string.
  448. EP_S_CANT_PERFORM_OP - The binding was unsuccessful, possibly because
  449. the protocol sequence is not supported.
  450. --*/
  451. {
  452. RPC_STATUS Status = EPT_S_CANT_PERFORM_OP;
  453. RPC_CHAR * BindingString = NULL;
  454. unsigned int i, Count;
  455. BOOL fHttp = FALSE;
  456. Count = sizeof(EpMapperTable)/sizeof(EpMapperTable[0]);
  457. // If Protseq == NULL use lrpc.
  458. if (NULL == Protseq)
  459. {
  460. ASSERT(NWAddress == 0);
  461. BindingString = RPC_STRING_LITERAL("ncalrpc:[epmapper]");
  462. }
  463. else
  464. {
  465. char * AnsiProtseq;
  466. AnsiProtseq = (char *) _alloca(1+RpcpStringLength(Protseq));
  467. if (!AnsiProtseq)
  468. {
  469. return RPC_S_OUT_OF_MEMORY;
  470. }
  471. SimpleUnicodeToAnsi(Protseq, AnsiProtseq);
  472. if (Options)
  473. {
  474. fHttp = (0 == RpcpStringCompare(Protseq, RPC_STRING_LITERAL("ncacn_http")));
  475. }
  476. for (i = 0; i < Count; i++)
  477. {
  478. if (RpcpStringCompareA(AnsiProtseq,
  479. (char PAPI *) EpMapperTable[i].Protseq) )
  480. continue;
  481. // Found it.
  482. RPC_CHAR * Endpoint;
  483. Endpoint = (RPC_CHAR *) _alloca(sizeof(RPC_CHAR) * (1+strlen(EpMapperTable[i].Endpoint)));
  484. if (!Endpoint)
  485. {
  486. return RPC_S_OUT_OF_MEMORY;
  487. }
  488. SimpleAnsiToPlatform(EpMapperTable[i].Endpoint, Endpoint);
  489. Status = RpcStringBindingCompose( NULL,
  490. Protseq,
  491. NWAddress,
  492. Endpoint,
  493. (fHttp ? Options : 0),
  494. &BindingString);
  495. break;
  496. }
  497. }
  498. if (BindingString)
  499. {
  500. Status = RpcBindingFromStringBinding(BindingString, MapperHandle);
  501. }
  502. if (BindingString != NULL && Protseq != NULL)
  503. {
  504. RpcStringFree(&BindingString);
  505. }
  506. if (Status != RPC_S_OK)
  507. {
  508. return(EPT_S_CANT_PERFORM_OP);
  509. }
  510. if (AuthInfo && (RpcpStringNCompare(Protseq, RPC_STRING_LITERAL("ncacn_"), 6) == 0))
  511. {
  512. Status = SetAuthInformation (*MapperHandle, AuthInfo);
  513. if (Status != RPC_S_OK)
  514. return Status;
  515. }
  516. Status = RpcMgmtSetComTimeout(*MapperHandle, ConnTimeout);
  517. if (Status != RPC_S_OK)
  518. {
  519. return(EPT_S_CANT_PERFORM_OP);
  520. }
  521. return(RPC_S_OK);
  522. }
  523. void RPC_ENTRY
  524. EpFreeLookupHandle (
  525. IN void PAPI * EpLookupHandle
  526. )
  527. {
  528. EP_LOOKUP_DATA PAPI * EpLookupData = (EP_LOOKUP_DATA PAPI *) EpLookupHandle;
  529. if ( EpLookupData->Endpoints != 0 )
  530. {
  531. while ( EpLookupData->NumberOfEndpoints > 0 )
  532. {
  533. EpLookupData->NumberOfEndpoints -= 1;
  534. delete EpLookupData->Endpoints[EpLookupData->NumberOfEndpoints];
  535. }
  536. RpcpFarFree(EpLookupData->Endpoints);
  537. }
  538. RpcpFarFree(EpLookupData);
  539. }
  540. HPROCESS hRpcssContext = 0;
  541. RPC_STATUS RPC_ENTRY
  542. I_RpcServerAllocateIpPort(
  543. IN DWORD Flags,
  544. OUT USHORT *pPort
  545. )
  546. {
  547. USHORT Port;
  548. RPC_STATUS status;
  549. RPC_BINDING_HANDLE hServer;
  550. PORT_TYPE type;
  551. *pPort = 0;
  552. // Figure out what sort of port to allocate
  553. if (Flags & RPC_C_USE_INTERNET_PORT)
  554. {
  555. type = PORT_INTERNET;
  556. Flags &= ~RPC_C_USE_INTERNET_PORT;
  557. }
  558. else if (Flags & RPC_C_USE_INTRANET_PORT)
  559. {
  560. type = PORT_INTRANET;
  561. Flags &= ~RPC_C_USE_INTRANET_PORT;
  562. }
  563. else
  564. {
  565. type = PORT_DEFAULT;
  566. }
  567. // Setup process context in the endpoint mapper if needed.
  568. if (hRpcssContext == 0)
  569. {
  570. HPROCESS hProcess;
  571. status = RpcBindingFromStringBinding(RPC_STRING_LITERAL("ncalrpc:[epmapper]"),
  572. &hServer);
  573. if (status != RPC_S_OK)
  574. {
  575. return(status);
  576. }
  577. hProcess = 0;
  578. status = OpenEndpointMapper(hServer,
  579. &hProcess);
  580. RPC_STATUS statust =
  581. RpcBindingFree(&hServer);
  582. ASSERT(statust == RPC_S_OK);
  583. if (status != RPC_S_OK)
  584. {
  585. return(status);
  586. }
  587. GlobalMutexRequest();
  588. if (hRpcssContext != 0)
  589. {
  590. ASSERT(hRpcssContext != hProcess);
  591. RpcSmDestroyClientContext(&hProcess);
  592. }
  593. else
  594. {
  595. hRpcssContext = hProcess;
  596. }
  597. GlobalMutexClear();
  598. }
  599. // Actually allocate a port.
  600. RPC_STATUS allocstatus;
  601. status = AllocateReservedIPPort(hRpcssContext,
  602. type,
  603. &allocstatus,
  604. pPort);
  605. if (status != RPC_S_OK)
  606. {
  607. ASSERT(*pPort == 0);
  608. return(status);
  609. }
  610. return(allocstatus);
  611. }
  612. // Very special code for our older (NT 3.1 Era) servers.
  613. //
  614. // These server send out unique pointers which will confuse our
  615. // stubs while unmarshalling. Here we go through and fixup the
  616. // node id's to look like full pointers.
  617. //
  618. // This code can be removed when support for NT 3.1 era servers
  619. // is no longer required.
  620. extern "C"
  621. void FixupForUniquePointerServers(PRPC_MESSAGE pMessage)
  622. {
  623. int CurrentPointer = 3;
  624. unsigned int NumberOfPointers;
  625. unsigned int i;
  626. unsigned long __RPC_FAR *pBuffer;
  627. pBuffer = (unsigned long __RPC_FAR *) pMessage->Buffer;
  628. // The output buffer looks like:
  629. // [ out-context handle (20b) ]
  630. // [ count (4b) ]
  631. // [ max (4b) ]
  632. // [ min (4b) ]
  633. // [ length (4b) ] // should be the same as count
  634. // [ pointer node (count of them) ]
  635. ASSERT(pBuffer[5] == pBuffer[8]);
  636. NumberOfPointers = pBuffer[5];
  637. ASSERT(pMessage->BufferLength >= 4 * 9 + 4 * NumberOfPointers);
  638. for(i = 0; i < NumberOfPointers; i++)
  639. {
  640. if (pBuffer[9 + i] != 0)
  641. {
  642. pBuffer[9 + i] = CurrentPointer;
  643. CurrentPointer++;
  644. }
  645. }
  646. return;
  647. }
  648. #if defined(WIN) || defined(WIN32)
  649. void __RPC_FAR * __RPC_API
  650. MIDL_user_allocate(
  651. size_t Size
  652. )
  653. /*++
  654. Routine Description:
  655. MIDL generated stubs need this routine.
  656. Arguments:
  657. Size - Supplies the length of the memory to allocate in bytes.
  658. Return Value:
  659. The buffer allocated will be returned, if there is sufficient memory,
  660. otherwise, zero will be returned.
  661. --*/
  662. {
  663. void PAPI * pvBuf;
  664. pvBuf = I_RpcAllocate(Size);
  665. return(pvBuf);
  666. }
  667. void __RPC_API
  668. MIDL_user_free (
  669. void __RPC_FAR *Buf
  670. )
  671. {
  672. I_RpcFree(Buf);
  673. }
  674. #endif