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.

770 lines
23 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation, 1993 - 1999
  3. Module Name:
  4. epmgmt.c
  5. Abstract:
  6. We implement the endpoint mapper management routines: RpcMgmtEpEltInqBegin,
  7. RpcMgmtEpEltInqDone, RpcMgmtEpEltInqNext, and RpcMgmtEpUnregister.
  8. Author:
  9. Michael Montague (mikemon) 14-Apr-1993
  10. Revision History:
  11. --*/
  12. #include <precomp.hxx>
  13. #include <epmp.h>
  14. #include <twrproto.h>
  15. #include <epmap.h>
  16. #include <charconv.hxx>
  17. #define EP_INQUIRY_CONTEXT_MAGIC_VALUE 0xBAD00DADL
  18. typedef struct _EP_INQUIRY_CONTEXT
  19. {
  20. unsigned long MagicValue;
  21. RPC_BINDING_HANDLE BindingHandle;
  22. ept_lookup_handle_t ContextHandle;
  23. unsigned long InquiryType;
  24. RPC_IF_ID IfId;
  25. unsigned long VersOption;
  26. UUID ObjectUuid;
  27. } EP_INQUIRY_CONTEXT;
  28. #define NOMOREEPS 0xFFFFFFFEL
  29. #define NOMOREEPS_HANDLE ((ept_lookup_handle_t)ULongToPtr(NOMOREEPS))
  30. // const ept_lookup_handle_t NOMOREEPS_HANDLE = (ept_lookup_handle_t)ULongToPtr(NOMOREEPS);
  31. RPC_STATUS RPC_ENTRY
  32. RpcMgmtEpEltInqBegin (
  33. IN RPC_BINDING_HANDLE EpBinding OPTIONAL,
  34. IN unsigned long InquiryType,
  35. IN RPC_IF_ID __RPC_FAR * IfId OPTIONAL,
  36. IN unsigned long VersOption OPTIONAL,
  37. IN UUID __RPC_FAR * ObjectUuid OPTIONAL,
  38. OUT RPC_EP_INQ_HANDLE __RPC_FAR * InquiryContext
  39. )
  40. /*++
  41. Routine Description:
  42. This routine is used to create an inquiry context for viewing the elements
  43. in a local or remote endpoint mapper database.
  44. Arguments:
  45. EpBinding - Optionally supplies a binding indicating the endpoint mapper on
  46. which host should be interogated. The binding must have a nil object
  47. uuid; otherwise, EPT_S_CANT_PERFORM_OP will be returned. To specify
  48. this host (meaning the one the application is running on), specify NULL
  49. for this argument. Only the network address and transport type will
  50. be used from the binding handle.
  51. InquiryType - Supplies the type of interogation to be performed; this must
  52. be one of: RPC_C_EP_ALL_ELTS, RPC_C_EP_MATCH_BY_IF,
  53. RPC_C_EP_MATCH_BY_OBJ, and RPC_C_EP_MATCH_BY_BOTH.
  54. IfId - Optionally supplies the interface identifier we are interogating
  55. the endpoint mapper with. This argument must be supplied when the
  56. inquiry type is RPC_C_EP_MATCH_BY_IF or RPC_C_EP_MATCH_BY_BOTH;
  57. otherwise, this argument is ignored and NULL can be supplied.
  58. VersOption - Optionally supplies a flag specifying how interface versions
  59. are to be matched. This argument must be supplied when IfId is
  60. supplied; otherwise, this argument is ignored. Valid values for this
  61. flag are: RPC_C_VERS_ALL, RPC_C_VERS_COMPATIBLE, RPC_C_VERS_EXACT,
  62. RPC_C_VERS_MAJOR_ONLY, and RPC_C_VERS_UPTO.
  63. ObjectUuid - Optionally supplies the object uuid find in the endpoint
  64. mapper database. This argument must be supplied when the inquiry
  65. typedef is RPC_C_EP_MATCH_BY_OBJ or RPC_EP_MATCH_BY_BOTH; otherwise,
  66. this argument is ignored and NULL can be supplied.
  67. InquiryContext - Returns a context handle which can be passed to
  68. RpcMgmtEpEltInqNext to obtain the results of the interogation of the
  69. endpoint mapper database.
  70. Return Value:
  71. RPC_S_INVALID_ARG
  72. EPT_S_CANT_PERFORM_OP
  73. RPC_S_OUT_OF_MEMORY
  74. --*/
  75. {
  76. RPC_STATUS RpcStatus;
  77. RPC_CHAR __RPC_FAR * ProtocolSequence;
  78. RPC_CHAR __RPC_FAR * NetworkAddress;
  79. RPC_CHAR __RPC_FAR * Options;
  80. EP_INQUIRY_CONTEXT __RPC_FAR * EpInquiryContext;
  81. unsigned Timeout;
  82. switch ( InquiryType )
  83. {
  84. case RPC_C_EP_ALL_ELTS :
  85. IfId = 0;
  86. ObjectUuid = 0;
  87. break;
  88. case RPC_C_EP_MATCH_BY_IF :
  89. ObjectUuid = 0;
  90. // no break
  91. case RPC_C_EP_MATCH_BY_BOTH :
  92. if ( IfId == 0 )
  93. {
  94. return(RPC_S_INVALID_ARG);
  95. }
  96. if ( ( VersOption != RPC_C_VERS_ALL )
  97. && ( VersOption != RPC_C_VERS_COMPATIBLE )
  98. && ( VersOption != RPC_C_VERS_EXACT )
  99. && ( VersOption != RPC_C_VERS_MAJOR_ONLY )
  100. && ( VersOption != RPC_C_VERS_UPTO ) )
  101. {
  102. return(RPC_S_INVALID_ARG);
  103. }
  104. if ( ( InquiryType == RPC_C_EP_MATCH_BY_BOTH )
  105. && ( ObjectUuid == 0 ) )
  106. {
  107. return(RPC_S_INVALID_ARG);
  108. }
  109. break;
  110. case RPC_C_EP_MATCH_BY_OBJ :
  111. IfId = 0;
  112. if ( ObjectUuid == 0 )
  113. {
  114. return(RPC_S_INVALID_ARG);
  115. }
  116. break;
  117. default:
  118. return(RPC_S_INVALID_ARG);
  119. }
  120. // At this point, we have validated the InquiryType, IfId, VersOption,
  121. // and ObjectUuid parameters.
  122. if ( EpBinding != 0 )
  123. {
  124. UUID Uuid;
  125. int Result;
  126. RPC_CHAR __RPC_FAR * StringBinding;
  127. RpcStatus = RpcBindingInqObject(EpBinding, &Uuid);
  128. if ( RpcStatus != RPC_S_OK )
  129. {
  130. return(RpcStatus);
  131. }
  132. Result = UuidIsNil(&Uuid, &RpcStatus);
  133. if ( Result == 0 )
  134. {
  135. return(EPT_S_CANT_PERFORM_OP);
  136. }
  137. RpcStatus = RpcBindingToStringBinding(EpBinding, &StringBinding);
  138. if ( RpcStatus != RPC_S_OK )
  139. {
  140. return(RpcStatus);
  141. }
  142. RpcStatus = RpcStringBindingParse(StringBinding, 0, &ProtocolSequence,
  143. &NetworkAddress, 0, &Options);
  144. RpcStringFree(&StringBinding);
  145. if ( RpcStatus != RPC_S_OK )
  146. {
  147. return(RpcStatus);
  148. }
  149. RpcStatus = RpcMgmtInqComTimeout(EpBinding, &Timeout);
  150. if ( RpcStatus != RPC_S_OK )
  151. {
  152. RpcStringFree(&ProtocolSequence);
  153. RpcStringFree(&NetworkAddress);
  154. RpcStringFree(&Options);
  155. return(RpcStatus);
  156. }
  157. }
  158. else
  159. {
  160. NetworkAddress = 0;
  161. ProtocolSequence = 0;
  162. Options = 0;
  163. Timeout = RPC_C_BINDING_DEFAULT_TIMEOUT;
  164. }
  165. // When we reach here, the EpBinding will have been validated, and the
  166. // network address and protocol sequence to be used to reach the endpoint
  167. // mapper have been determined.
  168. // Thus all of the arguments will have been validated.
  169. EpInquiryContext = (EP_INQUIRY_CONTEXT __RPC_FAR *) I_RpcAllocate(
  170. sizeof(EP_INQUIRY_CONTEXT));
  171. if ( EpInquiryContext == 0 )
  172. {
  173. if (EpBinding != 0)
  174. {
  175. RpcStringFree(&ProtocolSequence);
  176. RpcStringFree(&NetworkAddress);
  177. RpcStringFree(&Options);
  178. }
  179. return(RPC_S_OUT_OF_MEMORY);
  180. }
  181. RpcStatus = BindToEpMapper(&(EpInquiryContext->BindingHandle),
  182. NetworkAddress,
  183. ProtocolSequence,
  184. Options,
  185. Timeout,
  186. INFINITE, // CallTimeout
  187. NULL // AuthInfo
  188. );
  189. if (EpBinding != 0)
  190. {
  191. RpcStringFree(&ProtocolSequence);
  192. RpcStringFree(&NetworkAddress);
  193. RpcStringFree(&Options);
  194. }
  195. if ( RpcStatus != RPC_S_OK )
  196. {
  197. return(RpcStatus);
  198. }
  199. EpInquiryContext->MagicValue = EP_INQUIRY_CONTEXT_MAGIC_VALUE;
  200. EpInquiryContext->ContextHandle = 0;
  201. EpInquiryContext->InquiryType = InquiryType;
  202. if ( IfId != 0 )
  203. {
  204. EpInquiryContext->IfId = *IfId;
  205. }
  206. EpInquiryContext->VersOption = VersOption;
  207. if ( ObjectUuid != 0 )
  208. {
  209. EpInquiryContext->ObjectUuid = *ObjectUuid;
  210. }
  211. *InquiryContext = (RPC_EP_INQ_HANDLE)EpInquiryContext;
  212. return(RPC_S_OK);
  213. }
  214. RPC_STATUS RPC_ENTRY
  215. RpcMgmtEpEltInqDone (
  216. IN OUT RPC_EP_INQ_HANDLE __RPC_FAR * InquiryContext
  217. )
  218. /*++
  219. Routine Description:
  220. The context handle used to interogate an endpoint mapper database is
  221. cleaned up in this routine.
  222. Arguments:
  223. InquiryContext - Supplies the context handle to be deleted; on return,
  224. it will be set to zero.
  225. Return Value:
  226. RPC_S_OK - Everything worked out just fine.
  227. RPC_S_INVALID_ARG - The supplied value supplied for the inquiry context
  228. is not an endpoint mapper inquiry context.
  229. --*/
  230. {
  231. EP_INQUIRY_CONTEXT __RPC_FAR * EpInquiryContext =
  232. (EP_INQUIRY_CONTEXT __RPC_FAR *) *InquiryContext;
  233. if ( EpInquiryContext->MagicValue != EP_INQUIRY_CONTEXT_MAGIC_VALUE )
  234. {
  235. return(RPC_S_INVALID_ARG);
  236. }
  237. RpcBindingFree(&(EpInquiryContext->BindingHandle));
  238. if ( (EpInquiryContext->ContextHandle != 0) &&
  239. (EpInquiryContext->ContextHandle != NOMOREEPS_HANDLE) )
  240. {
  241. RpcSsDestroyClientContext(&(EpInquiryContext->ContextHandle));
  242. }
  243. I_RpcFree(EpInquiryContext);
  244. *InquiryContext = 0;
  245. return(RPC_S_OK);
  246. }
  247. RPC_STATUS RPC_ENTRY
  248. RpcMgmtEpEltInqNextW (
  249. IN RPC_EP_INQ_HANDLE InquiryContext,
  250. OUT RPC_IF_ID __RPC_FAR * IfId,
  251. OUT RPC_BINDING_HANDLE __RPC_FAR * Binding OPTIONAL,
  252. OUT UUID __RPC_FAR * ObjectUuid OPTIONAL,
  253. OUT unsigned short __RPC_FAR * __RPC_FAR * Annotation OPTIONAL
  254. )
  255. /*++
  256. Routine Description:
  257. This routine is the unicode thunk to RpcMgmtEpEltInqNextA.
  258. --*/
  259. {
  260. unsigned char * AnsiAnnotation;
  261. RPC_STATUS RpcStatus;
  262. RpcStatus = RpcMgmtEpEltInqNextA( InquiryContext,
  263. IfId,
  264. Binding,
  265. ObjectUuid,
  266. Annotation ? &AnsiAnnotation : 0
  267. );
  268. if ( (RpcStatus == RPC_S_OK) && (Annotation) )
  269. {
  270. RpcStatus = A2WAttachHelper((char *)AnsiAnnotation, Annotation);
  271. I_RpcFree(AnsiAnnotation);
  272. }
  273. return RpcStatus;
  274. }
  275. RPC_STATUS RPC_ENTRY
  276. RpcMgmtEpEltInqNextA (
  277. IN RPC_EP_INQ_HANDLE InquiryContext,
  278. OUT RPC_IF_ID __RPC_FAR * IfId,
  279. OUT RPC_BINDING_HANDLE __RPC_FAR * Binding OPTIONAL,
  280. OUT UUID __RPC_FAR * ObjectUuid OPTIONAL,
  281. OUT unsigned char __RPC_FAR * __RPC_FAR * Annotation OPTIONAL
  282. )
  283. /*++
  284. Routine Description:
  285. An application will use this routine to obtain the results of an
  286. interogation of the endpoint mapper database.
  287. Arguments:
  288. InquiryContext - Supplies a context handle for the interogation.
  289. IfId - Returns the interface identifier of the element which was
  290. found in the endpoint mapper database.
  291. Binding - Optionally returns the binding handle contained in the element.
  292. Annotation - Optionally returns the annotation stored in the element.
  293. Return Value:
  294. RPC_S_OK - We have successfully returned an element from the endpoint
  295. mapper database.
  296. RPC_S_OUT_OF_MEMORY - Insufficient memory is available to perform the
  297. operation.
  298. RPC_S_INVALID_ARG - The supplied value for the inquiry context is not
  299. a valid endpoint mapper inquiry context.
  300. EPT_S_CANT_PERFORM_OP -
  301. RPC_X_NO_MORE_ENTRIES - No more entries are available. This will be
  302. returned after all of the entries have been returned from the
  303. endpoint mapper.
  304. --*/
  305. {
  306. EP_INQUIRY_CONTEXT __RPC_FAR * EpInquiryContext =
  307. (EP_INQUIRY_CONTEXT __RPC_FAR *) InquiryContext;
  308. unsigned long Returned;
  309. ept_entry_t EpEntry;
  310. error_status ErrorStatus;
  311. RPC_STATUS RpcStatus = RPC_S_OK;
  312. unsigned char __RPC_FAR * StringBinding;
  313. unsigned char __RPC_FAR * ProtocolSequence;
  314. unsigned char __RPC_FAR * Endpoint;
  315. unsigned char __RPC_FAR * NWAddress = 0;
  316. if ( EpInquiryContext->MagicValue != EP_INQUIRY_CONTEXT_MAGIC_VALUE )
  317. {
  318. return(RPC_S_INVALID_ARG);
  319. }
  320. if ( EpInquiryContext->ContextHandle == NOMOREEPS_HANDLE )
  321. {
  322. return (RPC_X_NO_MORE_ENTRIES);
  323. }
  324. while (1)
  325. {
  326. EpEntry.tower = 0;
  327. RpcTryExcept
  328. {
  329. ept_lookup(EpInquiryContext->BindingHandle,
  330. EpInquiryContext->InquiryType, &(EpInquiryContext->ObjectUuid),
  331. &(EpInquiryContext->IfId), EpInquiryContext->VersOption,
  332. &(EpInquiryContext->ContextHandle), 1, &Returned, &EpEntry,
  333. &ErrorStatus);
  334. }
  335. RpcExcept(I_RpcExceptionFilter(RpcExceptionCode()))
  336. {
  337. RpcStatus = RpcExceptionCode();
  338. }
  339. RpcEndExcept
  340. if ( RpcStatus == RPC_S_OK )
  341. {
  342. if ( ErrorStatus == EP_S_NOT_REGISTERED )
  343. {
  344. RpcStatus = RPC_X_NO_MORE_ENTRIES;
  345. }
  346. else if ( ErrorStatus != 0 )
  347. {
  348. RpcStatus = EPT_S_CANT_PERFORM_OP;
  349. }
  350. }
  351. if ( ( RpcStatus == RPC_S_OK )
  352. && ( Returned != 1 ) )
  353. {
  354. RpcStatus = EPT_S_CANT_PERFORM_OP;
  355. }
  356. if (EpInquiryContext->ContextHandle == 0)
  357. {
  358. EpInquiryContext->ContextHandle = NOMOREEPS_HANDLE;
  359. }
  360. if ( RpcStatus != RPC_S_OK )
  361. {
  362. if (RpcStatus == RPC_S_SERVER_UNAVAILABLE)
  363. {
  364. RpcStatus = RPC_X_NO_MORE_ENTRIES;
  365. }
  366. return(RpcStatus);
  367. }
  368. RpcStatus = TowerExplode(EpEntry.tower, IfId, 0,
  369. (char __RPC_FAR * __RPC_FAR *) &ProtocolSequence,
  370. (char __RPC_FAR * __RPC_FAR *) &Endpoint,
  371. (char __RPC_FAR * __RPC_FAR *) &NWAddress
  372. );
  373. MIDL_user_free(EpEntry.tower);
  374. if (RpcStatus != RPC_S_OK)
  375. {
  376. if ( (EpInquiryContext->ContextHandle == 0) || (EpInquiryContext->ContextHandle == NOMOREEPS_HANDLE) )
  377. {
  378. EpInquiryContext->ContextHandle = NOMOREEPS_HANDLE;
  379. return(RPC_X_NO_MORE_ENTRIES);
  380. }
  381. else
  382. {
  383. RpcStatus = RPC_S_OK;
  384. continue;
  385. }
  386. }
  387. else
  388. {
  389. //Tower Explode returned Success
  390. if ( Binding != 0 )
  391. {
  392. if ( RpcStatus != RPC_S_OK )
  393. {
  394. return(RpcStatus);
  395. }
  396. RpcStatus = RpcStringBindingComposeA(0,
  397. ProtocolSequence, NWAddress,
  398. Endpoint, 0, &StringBinding);
  399. if ( RpcStatus == RPC_S_OK )
  400. {
  401. RpcStatus = RpcBindingFromStringBindingA(
  402. StringBinding,
  403. Binding
  404. );
  405. RpcStringFreeA(&StringBinding);
  406. }
  407. if ( RpcStatus != RPC_S_OK )
  408. {
  409. RpcStringFreeA(&ProtocolSequence);
  410. RpcStringFreeA(&Endpoint);
  411. if (NWAddress != 0)
  412. {
  413. RpcStringFreeA(&NWAddress);
  414. }
  415. if ( (EpInquiryContext->ContextHandle == 0) || (EpInquiryContext->ContextHandle == NOMOREEPS_HANDLE) )
  416. {
  417. EpInquiryContext->ContextHandle = NOMOREEPS_HANDLE;
  418. return(RPC_X_NO_MORE_ENTRIES);
  419. }
  420. else
  421. {
  422. RpcStatus = RPC_S_OK;
  423. continue;
  424. }
  425. }
  426. }
  427. if (ObjectUuid != 0)
  428. {
  429. memcpy(ObjectUuid, &EpEntry.object, sizeof(UUID));
  430. }
  431. RpcStringFreeA(&ProtocolSequence);
  432. RpcStringFreeA(&Endpoint);
  433. if (NWAddress != 0)
  434. {
  435. RpcStringFreeA(&NWAddress);
  436. }
  437. }
  438. if ( Annotation != 0 )
  439. {
  440. *Annotation = (unsigned char __RPC_FAR *) I_RpcAllocate(
  441. strlen((LPCSTR) EpEntry.annotation) + 1);
  442. if ( *Annotation == 0 )
  443. {
  444. return(RPC_S_OUT_OF_MEMORY);
  445. }
  446. strcpy((LPSTR) *Annotation, (LPCSTR) EpEntry.annotation);
  447. }
  448. //MIDL_user_free(EpEntry.tower);
  449. break;
  450. }
  451. if (EpInquiryContext->ContextHandle == 0)
  452. {
  453. EpInquiryContext->ContextHandle = NOMOREEPS_HANDLE;
  454. }
  455. return(RpcStatus);
  456. }
  457. RPC_STATUS RPC_ENTRY
  458. RpcMgmtEpUnregister (
  459. IN RPC_BINDING_HANDLE EpBinding OPTIONAL,
  460. IN RPC_IF_ID __RPC_FAR * IfId,
  461. IN RPC_BINDING_HANDLE Binding,
  462. IN UUID __RPC_FAR * ObjectUuid OPTIONAL
  463. )
  464. /*++
  465. Routine Description:
  466. This routine is used by management applications to remote server address
  467. information from a local or remote endpoint map.
  468. Arguments:
  469. EpBinding - Optionally supplies a binding handle specifying which host
  470. from which to unregister remote server address information. To
  471. specify this host, supply zero for this argument. If a binding
  472. handle is supplied, then the object uuid in the binding handle must
  473. be zero.
  474. IfId - Supplies the interface identifier to be removed from the endpoint
  475. mapper database.
  476. Binding - Supplies the binding handle to be removed from the endpoint
  477. mapper database.
  478. ObjectUuid - Optionally supplies an object uuid to be removed; a value
  479. of zero indicates there is no object uuid to be removed.
  480. Return Value:
  481. RPC_S_OK -
  482. EPT_S_NOT_REGISTERED -
  483. EPT_S_CANT_PERFORM_OP -
  484. --*/
  485. {
  486. UUID Uuid;
  487. RPC_STATUS RpcStatus;
  488. int Result;
  489. RPC_CHAR * ProtocolSequence;
  490. RPC_CHAR * NetworkAddress;
  491. RPC_CHAR * Options;
  492. RPC_CHAR * StringBinding;
  493. unsigned char __RPC_FAR * AnsiProtocolSequence;
  494. unsigned char __RPC_FAR * AnsiNetworkAddress;
  495. unsigned char __RPC_FAR * AnsiEndpoint;
  496. unsigned char __RPC_FAR * AnsiStringBinding;
  497. RPC_BINDING_HANDLE EpBindingHandle;
  498. unsigned long UuidFlag;
  499. unsigned long ErrorStatus;
  500. twr_t __RPC_FAR * Tower;
  501. RPC_TRANSFER_SYNTAX TransferSyntax;
  502. unsigned Timeout;
  503. if ( EpBinding != 0 )
  504. {
  505. RpcStatus = RpcBindingInqObject(EpBinding, &Uuid);
  506. if ( RpcStatus != RPC_S_OK )
  507. {
  508. return(RpcStatus);
  509. }
  510. Result = UuidIsNil(&Uuid, &RpcStatus);
  511. if ( Result == 0 )
  512. {
  513. return(EPT_S_CANT_PERFORM_OP);
  514. }
  515. RpcStatus = RpcBindingToStringBinding(EpBinding, &StringBinding);
  516. if ( RpcStatus != RPC_S_OK )
  517. {
  518. return(RpcStatus);
  519. }
  520. RpcStatus = RpcStringBindingParse( StringBinding,
  521. 0,
  522. &ProtocolSequence,
  523. &NetworkAddress,
  524. 0,
  525. &Options);
  526. RpcStringFree(&StringBinding);
  527. if ( RpcStatus != RPC_S_OK )
  528. {
  529. return(RpcStatus);
  530. }
  531. RpcStatus = RpcMgmtInqComTimeout(EpBinding, &Timeout);
  532. if ( RpcStatus != RPC_S_OK )
  533. {
  534. RpcStringFree(&ProtocolSequence);
  535. RpcStringFree(&NetworkAddress);
  536. RpcStringFree(&Options);
  537. return(RpcStatus);
  538. }
  539. }
  540. else
  541. {
  542. NetworkAddress = 0;
  543. ProtocolSequence = 0;
  544. Options = 0;
  545. Timeout = RPC_C_BINDING_DEFAULT_TIMEOUT;
  546. }
  547. // When we reach here, the EpBinding will have been validated, and the
  548. // network address and protocol sequence to be used to reach the endpoint
  549. // mapper have been determined.
  550. RpcStatus = BindToEpMapper( &EpBindingHandle,
  551. NetworkAddress,
  552. ProtocolSequence,
  553. Options,
  554. Timeout,
  555. INFINITE, // CallTimeout
  556. NULL // AuthInfo
  557. );
  558. RpcStringFree(&ProtocolSequence);
  559. RpcStringFree(&NetworkAddress);
  560. RpcStringFree(&Options);
  561. if ( RpcStatus != RPC_S_OK )
  562. {
  563. return(RpcStatus);
  564. }
  565. RpcStatus = RpcBindingToStringBindingA(Binding, &AnsiStringBinding);
  566. if ( RpcStatus != RPC_S_OK )
  567. {
  568. return(RpcStatus);
  569. }
  570. RpcStatus = RpcStringBindingParseA( AnsiStringBinding,
  571. 0,
  572. &AnsiProtocolSequence,
  573. &AnsiNetworkAddress,
  574. &AnsiEndpoint,
  575. 0);
  576. RpcStringFreeA(&AnsiStringBinding);
  577. if ( RpcStatus != RPC_S_OK )
  578. {
  579. return(RpcStatus);
  580. }
  581. RpcStatus = TowerConstruct( IfId,
  582. &TransferSyntax,
  583. (LPSTR) AnsiProtocolSequence,
  584. (LPSTR) AnsiEndpoint,
  585. (LPSTR) AnsiNetworkAddress,
  586. &Tower);
  587. RpcStringFreeA(&AnsiProtocolSequence);
  588. RpcStringFreeA(&AnsiNetworkAddress);
  589. RpcStringFreeA(&AnsiEndpoint);
  590. if ( RpcStatus != RPC_S_OK )
  591. {
  592. return(RpcStatus);
  593. }
  594. if ( ObjectUuid != 0 )
  595. {
  596. Uuid = *ObjectUuid;
  597. UuidFlag = 1;
  598. }
  599. else
  600. {
  601. UuidFlag = 0;
  602. }
  603. ASSERT( RpcStatus == RPC_S_OK );
  604. RpcTryExcept
  605. {
  606. ept_mgmt_delete(EpBindingHandle, UuidFlag, &Uuid, Tower, &ErrorStatus);
  607. }
  608. RpcExcept(I_RpcExceptionFilter(RpcExceptionCode()))
  609. {
  610. RpcStatus = RpcExceptionCode();
  611. }
  612. RpcEndExcept
  613. if ( RpcStatus == RPC_S_OK )
  614. {
  615. if ( ErrorStatus != 0 )
  616. {
  617. RpcStatus = EPT_S_NOT_REGISTERED;
  618. }
  619. }
  620. else
  621. if ( RpcStatus == RPC_S_SERVER_UNAVAILABLE )
  622. {
  623. RpcStatus = EPT_S_NOT_REGISTERED;
  624. }
  625. RpcBindingFree(&EpBindingHandle);
  626. return(RpcStatus);
  627. }