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.

1432 lines
40 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation, 1991 - 1999
  3. Module Name:
  4. dceansi.cxx
  5. Abstract:
  6. This file contains the ansi (as opposed to unicode) versions of the
  7. runtime APIs. All of these APIs simply do conversions between ansi
  8. and unicode, and then call a unicode version of the API to do the
  9. work.
  10. Author:
  11. Michael Montague (mikemon) 18-Dec-1991
  12. Revision History:
  13. --*/
  14. #include <precomp.hxx>
  15. #include <wincrypt.h>
  16. #include <rpcssl.h>
  17. #include <CharConv.hxx>
  18. RPC_STATUS
  19. AnsiToUnicodeString (
  20. IN unsigned char * String,
  21. OUT UNICODE_STRING * UnicodeString
  22. )
  23. /*++
  24. Routine Description:
  25. This helper routine is used to convert an ansi string into a unicode
  26. string.
  27. Arguments:
  28. String - Supplies the ansi string (actually a zero terminated string)
  29. to convert into a unicode string.
  30. UnicodeString - Returns the unicode string. This string will have
  31. to be freed using RtlFreeUnicodeString by the caller.
  32. Return Value:
  33. RPC_S_OK - The ansi string was successfully converted into a unicode
  34. string.
  35. RPC_S_OUT_OF_MEMORY - Insufficient memory is available for the unicode
  36. string.
  37. --*/
  38. {
  39. NTSTATUS NtStatus;
  40. ANSI_STRING AnsiString;
  41. RtlInitAnsiString(&AnsiString,(PSZ) String);
  42. NtStatus = RtlAnsiStringToUnicodeString(UnicodeString,&AnsiString,TRUE);
  43. if (!NT_SUCCESS(NtStatus))
  44. return(RPC_S_OUT_OF_MEMORY);
  45. return(RPC_S_OK);
  46. }
  47. unsigned char *
  48. UnicodeToAnsiString (
  49. IN RPC_CHAR * WideCharString,
  50. OUT RPC_STATUS * RpcStatus
  51. )
  52. /*++
  53. Routine Description:
  54. This routine will convert a unicode string into an ansi string,
  55. including allocating memory for the ansi string.
  56. Arguments:
  57. WideCharString - Supplies the unicode string to be converted into
  58. an ansi string.
  59. RpcStatus - Returns the status of the operation; this will be one
  60. of the following values.
  61. RPC_S_OK - The unicode string has successfully been converted
  62. into an ansi string.
  63. RPC_S_OUT_OF_MEMORY - Insufficient memory is available to allocate
  64. the ansi string.
  65. Return Value:
  66. A pointer to the ansi string will be returned.
  67. --*/
  68. {
  69. NTSTATUS NtStatus;
  70. UNICODE_STRING UnicodeString;
  71. ANSI_STRING AnsiString;
  72. unsigned char * NewString;
  73. RtlInitUnicodeString(&UnicodeString,WideCharString);
  74. NtStatus = RtlUnicodeStringToAnsiString(&AnsiString,&UnicodeString,TRUE);
  75. if (!NT_SUCCESS(NtStatus))
  76. {
  77. *RpcStatus = RPC_S_OUT_OF_MEMORY;
  78. return(0);
  79. }
  80. NewString = new unsigned char[AnsiString.Length + 1];
  81. if (NewString == 0)
  82. {
  83. RtlFreeAnsiString(&AnsiString);
  84. *RpcStatus = RPC_S_OUT_OF_MEMORY;
  85. return(0);
  86. }
  87. memcpy(NewString,AnsiString.Buffer,AnsiString.Length + 1);
  88. RtlFreeAnsiString(&AnsiString);
  89. *RpcStatus = RPC_S_OK;
  90. return(NewString);
  91. }
  92. RPC_STATUS RPC_ENTRY
  93. THUNK_FN(RpcBindingFromStringBinding) (
  94. IN THUNK_CHAR *StringBinding,
  95. OUT RPC_BINDING_HANDLE PAPI * Binding
  96. )
  97. /*++
  98. Routine Description:
  99. This routine is the ansi thunk to RpcBindingFromStringBindingW.
  100. Return Value:
  101. RPC_S_OUT_OF_MEMORY - This value will be returned if there is
  102. insufficient memory available to allocate the unicode string.
  103. --*/
  104. {
  105. USES_CONVERSION;
  106. RPC_STATUS RpcStatus;
  107. CHeapInThunk thunkStringBinding;
  108. ATTEMPT_HEAP_IN_THUNK(thunkStringBinding, StringBinding);
  109. RpcStatus = RpcBindingFromStringBinding(thunkStringBinding, Binding);
  110. return(RpcStatus);
  111. }
  112. RPC_STATUS RPC_ENTRY
  113. THUNK_FN(RpcBindingToStringBinding) (
  114. IN RPC_BINDING_HANDLE Binding,
  115. OUT THUNK_CHAR **StringBinding
  116. )
  117. /*++
  118. Routine Description:
  119. This routine is the ansi thunk to RpcBindingToStringBindingW.
  120. Return Value:
  121. RPC_S_OUT_OF_MEMORY - We will return this value if we do not
  122. have enough memory to convert the unicode string binding
  123. into an ansi string binding.
  124. --*/
  125. {
  126. RPC_STATUS RpcStatus;
  127. COutDelThunk thunkStringBinding;
  128. USES_CONVERSION;
  129. RpcStatus = RpcBindingToStringBinding(Binding, thunkStringBinding);
  130. if (RpcStatus != RPC_S_OK)
  131. return(RpcStatus);
  132. ATTEMPT_OUT_THUNK(thunkStringBinding, StringBinding);
  133. return(RpcStatus);
  134. }
  135. RPC_STATUS RPC_ENTRY
  136. THUNK_FN(RpcStringBindingCompose) (
  137. IN THUNK_CHAR *ObjUuid OPTIONAL,
  138. IN THUNK_CHAR *Protseq OPTIONAL,
  139. IN THUNK_CHAR *NetworkAddr OPTIONAL,
  140. IN THUNK_CHAR *Endpoint OPTIONAL,
  141. IN THUNK_CHAR *Options OPTIONAL,
  142. OUT THUNK_CHAR **StringBinding OPTIONAL
  143. )
  144. /*++
  145. Routine Description:
  146. This routine is the ansi thunk to RpcStringBindingComposeW.
  147. Return Value:
  148. RPC_S_OUT_OF_MEMORY - If insufficient memory is available to
  149. convert unicode string into ansi strings (and back again),
  150. we will return this value.
  151. --*/
  152. {
  153. USES_CONVERSION;
  154. CHeapInThunk thunkedObjUuid;
  155. CStackInThunk thunkedProtseq;
  156. CHeapInThunk thunkedNetworkAddr;
  157. CHeapInThunk thunkedEndpoint;
  158. CHeapInThunk thunkedOptions;
  159. COutDelThunk thunkedStringBinding;
  160. RPC_STATUS RpcStatus;
  161. ATTEMPT_HEAP_IN_THUNK_OPTIONAL(thunkedObjUuid, ObjUuid);
  162. ATTEMPT_STACK_IN_THUNK_OPTIONAL(thunkedProtseq, Protseq);
  163. ATTEMPT_HEAP_IN_THUNK_OPTIONAL(thunkedNetworkAddr, NetworkAddr);
  164. ATTEMPT_HEAP_IN_THUNK_OPTIONAL(thunkedEndpoint, Endpoint);
  165. ATTEMPT_HEAP_IN_THUNK_OPTIONAL(thunkedOptions, Options);
  166. RpcStatus = RpcStringBindingCompose(thunkedObjUuid, thunkedProtseq,
  167. thunkedNetworkAddr, thunkedEndpoint, thunkedOptions,
  168. thunkedStringBinding);
  169. if (RpcStatus != RPC_S_OK)
  170. return(RpcStatus);
  171. if (ARGUMENT_PRESENT(StringBinding))
  172. {
  173. ATTEMPT_OUT_THUNK(thunkedStringBinding, StringBinding);
  174. }
  175. return(RpcStatus);
  176. }
  177. RPC_STATUS RPC_ENTRY
  178. THUNK_FN(RpcStringBindingParse) (
  179. IN THUNK_CHAR * StringBinding,
  180. OUT THUNK_CHAR **ObjUuid OPTIONAL,
  181. OUT THUNK_CHAR **Protseq OPTIONAL,
  182. OUT THUNK_CHAR **NetworkAddr OPTIONAL,
  183. OUT THUNK_CHAR **Endpoint OPTIONAL,
  184. OUT THUNK_CHAR **NetworkOptions OPTIONAL
  185. )
  186. /*++
  187. Routine Description:
  188. This routine is the ansi thunk to RpcStringBindingParseW.
  189. Return Value:
  190. RPC_S_OUT_OF_MEMORY - This will be returned if insufficient memory
  191. is available to convert the strings to and from unicode.
  192. --*/
  193. {
  194. USES_CONVERSION;
  195. CHeapInThunk thunkedStringBinding;
  196. COutDelThunk thunkedObjUuid;
  197. COutDelThunk thunkedProtseq;
  198. COutDelThunk thunkedNetworkAddr;
  199. COutDelThunk thunkedEndpoint;
  200. COutDelThunk thunkedNetworkOptions;
  201. RPC_STATUS RpcStatus;
  202. ATTEMPT_HEAP_IN_THUNK(thunkedStringBinding, StringBinding);
  203. RpcStatus = RpcStringBindingParse(thunkedStringBinding,
  204. thunkedObjUuid, thunkedProtseq, thunkedNetworkAddr,
  205. thunkedEndpoint, thunkedNetworkOptions);
  206. if (RpcStatus != RPC_S_OK)
  207. return(RpcStatus);
  208. if (ARGUMENT_PRESENT(Protseq))
  209. *Protseq = 0;
  210. if (ARGUMENT_PRESENT(NetworkAddr))
  211. *NetworkAddr = 0;
  212. if (ARGUMENT_PRESENT(Endpoint))
  213. *Endpoint = 0;
  214. if (ARGUMENT_PRESENT(NetworkOptions))
  215. *NetworkOptions = 0;
  216. if (ARGUMENT_PRESENT(ObjUuid))
  217. {
  218. RpcStatus = thunkedObjUuid.Convert();
  219. if (RpcStatus != RPC_S_OK)
  220. goto DeleteStringsAndReturn;
  221. *ObjUuid = thunkedObjUuid;
  222. }
  223. if (ARGUMENT_PRESENT(Protseq))
  224. {
  225. RpcStatus = thunkedProtseq.Convert();
  226. if (RpcStatus != RPC_S_OK)
  227. goto DeleteStringsAndReturn;
  228. *Protseq = thunkedProtseq;
  229. }
  230. if (ARGUMENT_PRESENT(NetworkAddr))
  231. {
  232. RpcStatus = thunkedNetworkAddr.Convert();
  233. if (RpcStatus != RPC_S_OK)
  234. goto DeleteStringsAndReturn;
  235. *NetworkAddr = thunkedNetworkAddr;
  236. }
  237. if (ARGUMENT_PRESENT(Endpoint))
  238. {
  239. RpcStatus = thunkedEndpoint.Convert();
  240. if (RpcStatus != RPC_S_OK)
  241. goto DeleteStringsAndReturn;
  242. *Endpoint = thunkedEndpoint;
  243. }
  244. if (ARGUMENT_PRESENT(NetworkOptions))
  245. {
  246. RpcStatus = thunkedNetworkOptions.Convert();
  247. if (RpcStatus != RPC_S_OK)
  248. goto DeleteStringsAndReturn;
  249. *NetworkOptions = thunkedNetworkOptions;
  250. }
  251. DeleteStringsAndReturn:
  252. if (RpcStatus != RPC_S_OK)
  253. {
  254. if (ARGUMENT_PRESENT(Protseq))
  255. {
  256. delete *Protseq;
  257. *Protseq = 0;
  258. }
  259. if (ARGUMENT_PRESENT(NetworkAddr))
  260. {
  261. delete *NetworkAddr;
  262. *NetworkAddr = 0;
  263. }
  264. if (ARGUMENT_PRESENT(Endpoint))
  265. {
  266. delete *Endpoint;
  267. *Endpoint = 0;
  268. }
  269. if (ARGUMENT_PRESENT(NetworkOptions))
  270. {
  271. delete *NetworkOptions;
  272. *NetworkOptions = 0;
  273. }
  274. }
  275. return(RpcStatus);
  276. }
  277. RPC_STATUS RPC_ENTRY
  278. THUNK_FN(RpcNetworkIsProtseqValid) (
  279. IN THUNK_CHAR *Protseq
  280. )
  281. /*++
  282. Routine Description:
  283. This routine is the ansi thunk to RpcNetworkIsProtseqValidW.
  284. Return Value:
  285. RPC_S_OUT_OF_MEMORY - We will return this value if we run out of
  286. memory trying to allocate space for the string.
  287. --*/
  288. {
  289. USES_CONVERSION;
  290. CStackInThunk thunkedProtseq;
  291. RPC_STATUS RpcStatus;
  292. ATTEMPT_STACK_IN_THUNK(thunkedProtseq, Protseq);
  293. RpcStatus = RpcNetworkIsProtseqValid(thunkedProtseq);
  294. return(RpcStatus);
  295. }
  296. RPC_STATUS RPC_ENTRY
  297. THUNK_FN(RpcNetworkInqProtseqs) (
  298. #ifdef UNICODE
  299. OUT RPC_PROTSEQ_VECTORA PAPI * PAPI * ProtseqVector
  300. #else
  301. OUT RPC_PROTSEQ_VECTORW PAPI * PAPI * ProtseqVector
  302. #endif
  303. )
  304. /*++
  305. Routine Description:
  306. This routine is the ansi thunk for RpcNetworkInqProtseqsW.
  307. Return Value:
  308. RPC_S_OUT_OF_MEMORY - Insufficient memory is available to convert
  309. the rpc protocol sequences from unicode into ansi.
  310. --*/
  311. {
  312. RPC_STATUS RpcStatus;
  313. RPC_CHAR *pString;
  314. unsigned int Index, Count;
  315. RpcStatus = RpcNetworkInqProtseqs(
  316. (RPC_PROTSEQ_VECTOR **) ProtseqVector);
  317. if (RpcStatus != RPC_S_OK)
  318. return(RpcStatus);
  319. for (Index = 0, Count = (*ProtseqVector)->Count; Index < Count; Index++)
  320. {
  321. pString = (RPC_CHAR *) (*ProtseqVector)->Protseq[Index];
  322. #ifdef UNICODE
  323. RpcStatus = W2AAttachHelper(pString, (char **) &((*ProtseqVector)->Protseq[Index]));
  324. #else
  325. RpcStatus = A2WAttachHelper((char *) pString, &((*ProtseqVector)->Protseq[Index]));
  326. #endif
  327. delete pString;
  328. if (RpcStatus != RPC_S_OK)
  329. {
  330. #ifdef UNICODE
  331. RpcProtseqVectorFreeA(ProtseqVector);
  332. #else
  333. RpcProtseqVectorFreeW(ProtseqVector);
  334. #endif
  335. return(RpcStatus);
  336. }
  337. }
  338. return(RPC_S_OK);
  339. }
  340. RPC_STATUS RPC_ENTRY
  341. THUNK_FN(RpcProtseqVectorFree) (
  342. #ifdef UNICODE
  343. IN OUT RPC_PROTSEQ_VECTORA PAPI * PAPI * ProtseqVector
  344. #else
  345. IN OUT RPC_PROTSEQ_VECTORW PAPI * PAPI * ProtseqVector
  346. #endif
  347. )
  348. /*++
  349. Routine Description:
  350. This routine is the ansi thunk for RpcProtseqVectorFreeW.
  351. --*/
  352. {
  353. return(RpcProtseqVectorFree((RPC_PROTSEQ_VECTOR **) ProtseqVector));
  354. }
  355. RPC_STATUS RPC_ENTRY
  356. THUNK_FN(I_RpcServerUseProtseq2) (
  357. IN THUNK_CHAR * NetworkAddress,
  358. IN THUNK_CHAR * Protseq,
  359. IN unsigned int MaxCalls,
  360. IN void PAPI * SecurityDescriptor,
  361. IN void * pPolicy
  362. )
  363. {
  364. USES_CONVERSION;
  365. CStackInThunk thunkProtseq;
  366. CHeapInThunk thunkNetworkAddress;
  367. RPC_STATUS RpcStatus;
  368. PRPC_POLICY Policy = (PRPC_POLICY) pPolicy;
  369. ATTEMPT_STACK_IN_THUNK(thunkProtseq, Protseq);
  370. ATTEMPT_HEAP_IN_THUNK_OPTIONAL(thunkNetworkAddress, NetworkAddress);
  371. RpcStatus = I_RpcServerUseProtseq2(thunkNetworkAddress, thunkProtseq, MaxCalls,
  372. SecurityDescriptor, (void *) Policy);
  373. return(RpcStatus);
  374. }
  375. RPC_STATUS RPC_ENTRY
  376. THUNK_FN(RpcServerUseProtseqEx) (
  377. IN THUNK_CHAR *Protseq,
  378. IN unsigned int MaxCalls,
  379. IN void PAPI * SecurityDescriptor,
  380. IN PRPC_POLICY Policy
  381. )
  382. /*++
  383. Routine Description:
  384. This is the ansi thunk to RpcServerUseProtseqW.
  385. Return Value:
  386. RPC_S_OUT_OF_MEMORY - If we do not have enough memory to convert
  387. the ansi strings into unicode strings, this value will be returned.
  388. --*/
  389. {
  390. return THUNK_FN(I_RpcServerUseProtseq2) (NULL, Protseq, MaxCalls, SecurityDescriptor, (void *) Policy) ;
  391. }
  392. RPC_STATUS RPC_ENTRY
  393. THUNK_FN(RpcServerUseProtseq) (
  394. IN THUNK_CHAR *Protseq,
  395. IN unsigned int MaxCalls,
  396. IN void PAPI * SecurityDescriptor OPTIONAL
  397. )
  398. {
  399. RPC_POLICY Policy ;
  400. Policy.Length = sizeof(RPC_POLICY) ;
  401. Policy.EndpointFlags = 0;
  402. Policy.NICFlags = 0;
  403. return THUNK_FN(I_RpcServerUseProtseq2) (NULL, Protseq, MaxCalls, SecurityDescriptor, (void *) &Policy) ;
  404. }
  405. RPC_STATUS RPC_ENTRY
  406. THUNK_FN(I_RpcServerUseProtseqEp2) (
  407. IN THUNK_CHAR * NetworkAddress,
  408. IN THUNK_CHAR *Protseq,
  409. IN unsigned int MaxCalls,
  410. IN THUNK_CHAR *Endpoint,
  411. IN void PAPI * SecurityDescriptor,
  412. IN void * pPolicy
  413. )
  414. /*++
  415. Routine Description:
  416. This is the ansi thunk to RpcServerUseProtseqEpW.
  417. Return Value:
  418. RPC_S_OUT_OF_MEMORY - If we do not have enough memory to convert
  419. the ansi strings into unicode strings, this value will be returned.
  420. --*/
  421. {
  422. USES_CONVERSION;
  423. CStackInThunk thunkedProtseq;
  424. CHeapInThunk thunkedEndpoint;
  425. CHeapInThunk thunkedNetworkAddress;
  426. PRPC_POLICY Policy = (PRPC_POLICY) pPolicy;
  427. ATTEMPT_STACK_IN_THUNK(thunkedProtseq, Protseq);
  428. ATTEMPT_HEAP_IN_THUNK_OPTIONAL(thunkedEndpoint, Endpoint);
  429. ATTEMPT_HEAP_IN_THUNK_OPTIONAL(thunkedNetworkAddress, NetworkAddress);
  430. return (I_RpcServerUseProtseqEp2(thunkedNetworkAddress, thunkedProtseq, MaxCalls,
  431. thunkedEndpoint, SecurityDescriptor,
  432. (void *) Policy));
  433. }
  434. RPC_STATUS RPC_ENTRY
  435. THUNK_FN(RpcServerUseProtseqEpEx) (
  436. IN THUNK_CHAR *Protseq,
  437. IN unsigned int MaxCalls,
  438. IN THUNK_CHAR *Endpoint,
  439. IN void PAPI * SecurityDescriptor,
  440. IN PRPC_POLICY Policy
  441. )
  442. /*++
  443. Routine Description:
  444. This is the ansi thunk to RpcServerUseProtseqEpW.
  445. Return Value:
  446. RPC_S_OUT_OF_MEMORY - If we do not have enough memory to convert
  447. the ansi strings into unicode strings, this value will be returned.
  448. --*/
  449. {
  450. return THUNK_FN(I_RpcServerUseProtseqEp2) (NULL, Protseq, MaxCalls, Endpoint,
  451. SecurityDescriptor, (void *) Policy) ;
  452. }
  453. RPC_STATUS RPC_ENTRY
  454. THUNK_FN(RpcServerUseProtseqEp) (
  455. IN THUNK_CHAR *Protseq,
  456. IN unsigned int MaxCalls,
  457. IN THUNK_CHAR *Endpoint,
  458. IN void PAPI * SecurityDescriptor
  459. )
  460. {
  461. RPC_POLICY Policy ;
  462. Policy.Length = sizeof(RPC_POLICY) ;
  463. Policy.EndpointFlags = 0;
  464. Policy.NICFlags = 0;
  465. return THUNK_FN(I_RpcServerUseProtseqEp2) (NULL, Protseq, MaxCalls, Endpoint,
  466. SecurityDescriptor, (void *) &Policy) ;
  467. }
  468. RPC_STATUS RPC_ENTRY
  469. THUNK_FN(RpcServerUseProtseqIfEx) (
  470. IN THUNK_CHAR *Protseq,
  471. IN unsigned int MaxCalls,
  472. IN RPC_IF_HANDLE IfSpec,
  473. IN void PAPI * SecurityDescriptor,
  474. IN PRPC_POLICY Policy
  475. )
  476. /*++
  477. Routine Description:
  478. This is the ansi thunk to RpcServerUseProtseqIfW.
  479. Return Value:
  480. RPC_S_OUT_OF_MEMORY - If we do not have enough memory to convert
  481. the ansi strings into unicode strings, this value will be returned.
  482. --*/
  483. {
  484. USES_CONVERSION;
  485. CStackInThunk thunkedProtseq;
  486. ATTEMPT_STACK_IN_THUNK(thunkedProtseq, Protseq);
  487. return (RpcServerUseProtseqIfEx(thunkedProtseq, MaxCalls,
  488. IfSpec, SecurityDescriptor, Policy));
  489. }
  490. RPC_STATUS RPC_ENTRY
  491. THUNK_FN(RpcServerUseProtseqIf) (
  492. IN THUNK_CHAR *Protseq,
  493. IN unsigned int MaxCalls,
  494. IN RPC_IF_HANDLE IfSpec,
  495. IN void PAPI * SecurityDescriptor
  496. )
  497. {
  498. RPC_POLICY Policy ;
  499. Policy.Length = sizeof(RPC_POLICY) ;
  500. Policy.EndpointFlags = 0;
  501. Policy.NICFlags = 0;
  502. return THUNK_FN(RpcServerUseProtseqIfEx) ( Protseq, MaxCalls, IfSpec,
  503. SecurityDescriptor, &Policy) ;
  504. }
  505. RPC_STATUS RPC_ENTRY
  506. THUNK_FN(RpcNsBindingInqEntryName) (
  507. IN RPC_BINDING_HANDLE Binding,
  508. IN unsigned long EntryNameSyntax,
  509. OUT THUNK_CHAR **EntryName
  510. )
  511. /*++
  512. Routine Description:
  513. This routine is the ansi thunk to RpcNsBindingInqEntryNameW.
  514. Return Value:
  515. RPC_S_OUT_OF_MEMORY - We will return this value if we do not
  516. have enough memory to convert the unicode entry name into
  517. an ansi entry name.
  518. --*/
  519. {
  520. RPC_STATUS RpcStatus;
  521. USES_CONVERSION;
  522. COutDelThunk thunkedEntryName;
  523. RpcStatus = RpcNsBindingInqEntryName(Binding, EntryNameSyntax,
  524. thunkedEntryName);
  525. if ( RpcStatus == RPC_S_NO_ENTRY_NAME )
  526. {
  527. ATTEMPT_OUT_THUNK(thunkedEntryName, EntryName);
  528. return(RPC_S_NO_ENTRY_NAME);
  529. }
  530. if ( RpcStatus != RPC_S_OK )
  531. {
  532. return(RpcStatus);
  533. }
  534. ATTEMPT_OUT_THUNK(thunkedEntryName, EntryName);
  535. return(RPC_S_OK);
  536. }
  537. RPC_STATUS RPC_ENTRY
  538. THUNK_FN(UuidToString) (
  539. IN UUID PAPI * Uuid,
  540. OUT THUNK_CHAR **StringUuid
  541. )
  542. /*++
  543. Routine Description:
  544. This routine converts a UUID into its string representation.
  545. Arguments:
  546. Uuid - Supplies the UUID to be converted into string representation.
  547. StringUuid - Returns the string representation of the UUID. The
  548. runtime will allocate the string. The caller is responsible for
  549. freeing the string using RpcStringFree.
  550. Return Value:
  551. RPC_S_OK - We successfully converted the UUID into its string
  552. representation.
  553. RPC_S_OUT_OF_MEMORY - Insufficient memory is available to allocate
  554. a string.
  555. --*/
  556. {
  557. // The string representation of a UUID is always 36 character long,
  558. // and we need one more for the terminating zero.
  559. RPC_CHAR String[37];
  560. RPC_STATUS RpcStatus;
  561. InitializeIfNecessary();
  562. ((RPC_UUID PAPI *) Uuid)->ConvertToString(String);
  563. String[36] = 0;
  564. #ifdef UNICODE
  565. return W2AAttachHelper(String, (char **)StringUuid);
  566. #else
  567. return A2WAttachHelper((char *)String, StringUuid);
  568. #endif
  569. }
  570. RPC_STATUS RPC_ENTRY
  571. THUNK_FN(UuidFromString) (
  572. IN THUNK_CHAR *StringUuid OPTIONAL,
  573. OUT UUID PAPI * Uuid
  574. )
  575. /*++
  576. Routine Description:
  577. We convert a UUID from its string representation into the binary
  578. representation.
  579. Arguments:
  580. StringUuid - Optionally supplies the string representation of the UUID;
  581. if this argument is not supplied, then the NIL UUID is returned.
  582. Uuid - Returns the binary representation of the UUID.
  583. Return Value:
  584. RPC_S_OK - The string representation was successfully converted into
  585. the binary representation.
  586. RPC_S_INVALID_STRING_UUID - The supplied string UUID is not correct.
  587. RPC_S_OUT_OF_MEMORY - Insufficient memory is available to convert the
  588. ansi string into a unicode string.
  589. --*/
  590. {
  591. RPC_UUID RpcUuid;
  592. RPC_STATUS RpcStatus;
  593. USES_CONVERSION;
  594. CHeapInThunk thunkedStringUuid;
  595. if ( StringUuid == 0 )
  596. {
  597. ((RPC_UUID PAPI *) Uuid)->SetToNullUuid();
  598. return(RPC_S_OK);
  599. }
  600. ATTEMPT_HEAP_IN_THUNK(thunkedStringUuid, StringUuid);
  601. if (RpcUuid.ConvertFromString(thunkedStringUuid) != 0)
  602. {
  603. return(RPC_S_INVALID_STRING_UUID);
  604. }
  605. ((RPC_UUID PAPI *) Uuid)->CopyUuid(&RpcUuid);
  606. return(RPC_S_OK);
  607. }
  608. RPC_STATUS RPC_ENTRY
  609. THUNK_FN(RpcServerRegisterAuthInfo) (
  610. IN THUNK_CHAR *ServerPrincName,
  611. IN unsigned long AuthnSvc,
  612. IN RPC_AUTH_KEY_RETRIEVAL_FN GetKeyFn OPTIONAL,
  613. IN void PAPI * Arg OPTIONAL
  614. )
  615. /*++
  616. Routine Description:
  617. This routine is the ansi thunk to RpcServerRegisterAuthInfoW.
  618. Return Value:
  619. RPC_S_OUT_OF_MEMORY - We will return this value if we do not have
  620. enough memory to convert the ansi server principal name into
  621. a unicode string.
  622. --*/
  623. {
  624. USES_CONVERSION;
  625. CHeapInThunk thunkedServerPrincName;
  626. RPC_STATUS RpcStatus;
  627. ATTEMPT_HEAP_IN_THUNK(thunkedServerPrincName, ServerPrincName);
  628. RpcStatus = RpcServerRegisterAuthInfo(thunkedServerPrincName, AuthnSvc,
  629. GetKeyFn, Arg);
  630. return(RpcStatus);
  631. }
  632. RPC_STATUS RPC_ENTRY
  633. THUNK_FN(RpcBindingInqAuthClient) (
  634. IN RPC_BINDING_HANDLE ClientBinding, OPTIONAL
  635. OUT RPC_AUTHZ_HANDLE PAPI * Privs,
  636. OUT THUNK_CHAR **PrincName, OPTIONAL
  637. OUT unsigned long PAPI * AuthnLevel, OPTIONAL
  638. OUT unsigned long PAPI * AuthnSvc, OPTIONAL
  639. OUT unsigned long PAPI * AuthzSvc OPTIONAL
  640. )
  641. {
  642. return THUNK_FN(RpcBindingInqAuthClientEx)( ClientBinding,
  643. Privs,
  644. PrincName,
  645. AuthnLevel,
  646. AuthnSvc,
  647. AuthzSvc,
  648. 0
  649. );
  650. }
  651. RPC_STATUS RPC_ENTRY
  652. THUNK_FN(RpcBindingInqAuthClientEx) (
  653. IN RPC_BINDING_HANDLE ClientBinding, OPTIONAL
  654. OUT RPC_AUTHZ_HANDLE PAPI * Privs,
  655. OUT THUNK_CHAR **ServerPrincName, OPTIONAL
  656. OUT unsigned long PAPI * AuthnLevel, OPTIONAL
  657. OUT unsigned long PAPI * AuthnSvc, OPTIONAL
  658. OUT unsigned long PAPI * AuthzSvc, OPTIONAL
  659. IN unsigned long Flags
  660. )
  661. /*++
  662. Routine Description:
  663. This routine is the ansi thunk for RpcBindingInqAuthClientW.
  664. Return Value:
  665. RPC_S_OUT_OF_MEMORY - If we can not allocate space to convert the
  666. unicode server principal name into unicode, we will return this
  667. value.
  668. --*/
  669. {
  670. RPC_STATUS RpcStatus;
  671. USES_CONVERSION;
  672. COutDelThunk thunkedServerPrincName;
  673. RpcStatus = RpcBindingInqAuthClientEx(ClientBinding,
  674. Privs,
  675. (ARGUMENT_PRESENT(ServerPrincName) ? (RPC_CHAR **)thunkedServerPrincName : 0),
  676. AuthnLevel,
  677. AuthnSvc,
  678. AuthzSvc,
  679. Flags);
  680. if ( RpcStatus != RPC_S_OK )
  681. {
  682. return(RpcStatus);
  683. }
  684. if (ARGUMENT_PRESENT(ServerPrincName))
  685. {
  686. ATTEMPT_OUT_THUNK_OPTIONAL(thunkedServerPrincName, ServerPrincName);
  687. }
  688. return(RpcStatus);
  689. }
  690. RPC_STATUS RPC_ENTRY
  691. THUNK_FN(RpcServerInqCallAttributes) (
  692. IN RPC_BINDING_HANDLE ClientBinding, OPTIONAL
  693. IN OUT void *RpcCallAttributes
  694. )
  695. /*++
  696. Routine Description:
  697. This routine is the ansi thunk for RpcServerInqCallAttributes.
  698. Return Value:
  699. RPC_S_OUT_OF_MEMORY - If we can not allocate space to convert the
  700. unicode server principal name into unicode, we will return this
  701. value.
  702. The API can in addition return all errors returned by the Unicode
  703. version.
  704. --*/
  705. {
  706. RPC_STATUS RpcStatus;
  707. USES_CONVERSION;
  708. COutDelThunk thunkedServerPrincName;
  709. RPC_CALL_ATTRIBUTES_V1_W *CallAttributesW;
  710. RPC_CALL_ATTRIBUTES_V1_A *CallAttributesA;
  711. unsigned char *OldClientPrincipalNameBuffer;
  712. RPC_CHAR *NewClientPrincipalNameBuffer = NULL;
  713. ULONG OldClientPrincipalNameBufferLength;
  714. ULONG NewClientPrincipalNameBufferLength;
  715. unsigned char *OldServerPrincipalNameBuffer;
  716. RPC_CHAR *NewServerPrincipalNameBuffer = NULL;
  717. ULONG OldServerPrincipalNameBufferLength;
  718. ULONG NewServerPrincipalNameBufferLength;
  719. // we use the same structure to pass to the unicode API, but
  720. // we save some data members
  721. CallAttributesW =
  722. (RPC_CALL_ATTRIBUTES_V1_W *)RpcCallAttributes;
  723. CallAttributesA =
  724. (RPC_CALL_ATTRIBUTES_V1_A *)RpcCallAttributes;
  725. if (CallAttributesW->Flags & RPC_QUERY_CLIENT_PRINCIPAL_NAME)
  726. {
  727. OldClientPrincipalNameBuffer = CallAttributesA->ClientPrincipalName;
  728. OldClientPrincipalNameBufferLength = CallAttributesA->ClientPrincipalNameBufferLength;
  729. if (OldClientPrincipalNameBufferLength != 0)
  730. {
  731. NewClientPrincipalNameBuffer = new RPC_CHAR[OldClientPrincipalNameBufferLength];
  732. if (NewClientPrincipalNameBuffer == NULL)
  733. {
  734. return RPC_S_OUT_OF_MEMORY;
  735. }
  736. }
  737. else
  738. {
  739. // here CallAttributesW->ClientPrincipalName must be NULL. If it's
  740. // not, the unicode function will return error. Delegate the check to it
  741. NewClientPrincipalNameBuffer = CallAttributesW->ClientPrincipalName;
  742. }
  743. }
  744. if (CallAttributesW->Flags & RPC_QUERY_SERVER_PRINCIPAL_NAME)
  745. {
  746. OldServerPrincipalNameBuffer = CallAttributesA->ServerPrincipalName;
  747. OldServerPrincipalNameBufferLength = CallAttributesA->ServerPrincipalNameBufferLength;
  748. if (OldServerPrincipalNameBufferLength != 0)
  749. {
  750. NewServerPrincipalNameBuffer = new RPC_CHAR[OldServerPrincipalNameBufferLength];
  751. if (NewServerPrincipalNameBuffer == NULL)
  752. {
  753. if ((CallAttributesW->Flags & RPC_QUERY_CLIENT_PRINCIPAL_NAME)
  754. && (OldClientPrincipalNameBufferLength != 0))
  755. {
  756. ASSERT(NewClientPrincipalNameBuffer != NULL);
  757. delete [] NewClientPrincipalNameBuffer;
  758. }
  759. return RPC_S_OUT_OF_MEMORY;
  760. }
  761. }
  762. else
  763. {
  764. // here CallAttributesW->ServerPrincipalName must be NULL. If it's
  765. // not, the unicode function will return error. Delegate the check to it
  766. NewServerPrincipalNameBuffer = CallAttributesW->ServerPrincipalName;
  767. }
  768. }
  769. // by now all buffers are allocated, so we don't have failure paths b/n
  770. // here and the API call
  771. if (CallAttributesW->Flags & RPC_QUERY_SERVER_PRINCIPAL_NAME)
  772. {
  773. CallAttributesW->ServerPrincipalName = NewServerPrincipalNameBuffer;
  774. CallAttributesW->ServerPrincipalNameBufferLength *= 2;
  775. }
  776. if (CallAttributesW->Flags & RPC_QUERY_CLIENT_PRINCIPAL_NAME)
  777. {
  778. CallAttributesW->ClientPrincipalName = NewClientPrincipalNameBuffer;
  779. CallAttributesW->ClientPrincipalNameBufferLength *= 2;
  780. }
  781. RpcStatus = RpcServerInqCallAttributes(ClientBinding,
  782. RpcCallAttributes
  783. );
  784. // restore user's values to the structure regardless of failure
  785. if (CallAttributesW->Flags & RPC_QUERY_CLIENT_PRINCIPAL_NAME)
  786. {
  787. NewClientPrincipalNameBufferLength = CallAttributesA->ClientPrincipalNameBufferLength;
  788. CallAttributesA->ClientPrincipalNameBufferLength = OldClientPrincipalNameBufferLength;
  789. CallAttributesA->ClientPrincipalName = OldClientPrincipalNameBuffer;
  790. };
  791. if (CallAttributesW->Flags & RPC_QUERY_SERVER_PRINCIPAL_NAME)
  792. {
  793. NewServerPrincipalNameBufferLength = CallAttributesA->ServerPrincipalNameBufferLength;
  794. CallAttributesA->ServerPrincipalNameBufferLength = OldServerPrincipalNameBufferLength;
  795. CallAttributesA->ServerPrincipalName = OldServerPrincipalNameBuffer;
  796. };
  797. if ((RpcStatus != RPC_S_OK)
  798. && (RpcStatus != ERROR_MORE_DATA))
  799. {
  800. if ((CallAttributesW->Flags & RPC_QUERY_CLIENT_PRINCIPAL_NAME)
  801. && (OldClientPrincipalNameBufferLength != 0))
  802. {
  803. ASSERT(NewClientPrincipalNameBuffer != NULL);
  804. delete [] NewClientPrincipalNameBuffer;
  805. }
  806. if ((CallAttributesW->Flags & RPC_QUERY_SERVER_PRINCIPAL_NAME)
  807. && (OldServerPrincipalNameBufferLength != 0))
  808. {
  809. ASSERT(NewServerPrincipalNameBuffer != NULL);
  810. delete [] NewServerPrincipalNameBuffer;
  811. }
  812. return(RpcStatus);
  813. }
  814. ASSERT((RpcStatus == RPC_S_OK)
  815. || (RpcStatus == ERROR_MORE_DATA));
  816. if (CallAttributesW->Flags & RPC_QUERY_SERVER_PRINCIPAL_NAME)
  817. {
  818. CallAttributesW->ServerPrincipalNameBufferLength = NewServerPrincipalNameBufferLength >> 1;
  819. // if we returned non-zero, and there was enough space in the string to start with, we must
  820. // have returned a string as well
  821. if ((CallAttributesW->ServerPrincipalNameBufferLength > 0)
  822. && (CallAttributesW->ServerPrincipalNameBufferLength <= OldServerPrincipalNameBufferLength))
  823. {
  824. RtlUnicodeToMultiByteN((char *)CallAttributesA->ServerPrincipalName,
  825. CallAttributesA->ServerPrincipalNameBufferLength,
  826. NULL,
  827. NewServerPrincipalNameBuffer,
  828. NewServerPrincipalNameBufferLength);
  829. }
  830. }
  831. if (CallAttributesW->Flags & RPC_QUERY_CLIENT_PRINCIPAL_NAME)
  832. {
  833. CallAttributesW->ClientPrincipalNameBufferLength = NewClientPrincipalNameBufferLength >> 1;
  834. // if we returned non-zero, and there was enough space in the string to start with, we must
  835. // have returned a string as well
  836. if ((CallAttributesW->ClientPrincipalNameBufferLength > 0)
  837. && (CallAttributesW->ClientPrincipalNameBufferLength <= OldClientPrincipalNameBufferLength))
  838. {
  839. RtlUnicodeToMultiByteN((char *)CallAttributesA->ClientPrincipalName,
  840. CallAttributesA->ClientPrincipalNameBufferLength,
  841. NULL,
  842. NewClientPrincipalNameBuffer,
  843. NewClientPrincipalNameBufferLength);
  844. }
  845. }
  846. return(RpcStatus);
  847. }
  848. RPC_STATUS RPC_ENTRY
  849. THUNK_FN(RpcBindingInqAuthInfo) (
  850. IN RPC_BINDING_HANDLE Binding,
  851. OUT THUNK_CHAR **ServerPrincName, OPTIONAL
  852. OUT unsigned long PAPI * AuthnLevel, OPTIONAL
  853. OUT unsigned long PAPI * AuthnSvc, OPTIONAL
  854. OUT RPC_AUTH_IDENTITY_HANDLE PAPI * AuthIdentity, OPTIONAL
  855. OUT unsigned long PAPI * AuthzSvc OPTIONAL
  856. )
  857. /*++
  858. Routine Description:
  859. This routine is the ansi thunk for RpcBindingInqAuthInfoW.
  860. Return Value:
  861. RPC_S_OUT_OF_MEMORY - If we can not allocate space to convert the
  862. unicode server principal name into unicode, we will return this
  863. value.
  864. --*/
  865. {
  866. RPC_STATUS RpcStatus;
  867. return( THUNK_FN(RpcBindingInqAuthInfoEx) (
  868. Binding,
  869. ServerPrincName,
  870. AuthnLevel,
  871. AuthnSvc,
  872. AuthIdentity,
  873. AuthzSvc,
  874. 0,
  875. 0
  876. ) );
  877. }
  878. RPC_STATUS RPC_ENTRY
  879. THUNK_FN(RpcBindingInqAuthInfoEx) (
  880. IN RPC_BINDING_HANDLE Binding,
  881. OUT THUNK_CHAR **ServerPrincName, OPTIONAL
  882. OUT unsigned long PAPI * AuthnLevel, OPTIONAL
  883. OUT unsigned long PAPI * AuthnSvc, OPTIONAL
  884. OUT RPC_AUTH_IDENTITY_HANDLE PAPI * AuthIdentity, OPTIONAL
  885. OUT unsigned long PAPI * AuthzSvc, OPTIONAL
  886. IN unsigned long RpcSecurityQosVersion,
  887. OUT RPC_SECURITY_QOS * SecurityQOS
  888. )
  889. /*++
  890. Routine Description:
  891. This routine is the ansi thunk for RpcBindingInqAuthInfoW.
  892. Return Value:
  893. RPC_S_OUT_OF_MEMORY - If we can not allocate space to convert the
  894. unicode server principal name into unicode, we will return this
  895. value.
  896. --*/
  897. {
  898. RPC_STATUS RpcStatus;
  899. USES_CONVERSION;
  900. COutDelThunk thunkedServerPrincName;
  901. RpcStatus = RpcBindingInqAuthInfoEx(
  902. Binding,
  903. (ARGUMENT_PRESENT(ServerPrincName) ? (RPC_CHAR **)thunkedServerPrincName : 0),
  904. AuthnLevel,
  905. AuthnSvc,
  906. AuthIdentity,
  907. AuthzSvc,
  908. RpcSecurityQosVersion,
  909. SecurityQOS
  910. );
  911. if ( RpcStatus != RPC_S_OK )
  912. {
  913. return(RpcStatus);
  914. }
  915. if (ARGUMENT_PRESENT(ServerPrincName))
  916. {
  917. ATTEMPT_OUT_THUNK_OPTIONAL(thunkedServerPrincName, ServerPrincName);
  918. }
  919. return(RpcStatus);
  920. }
  921. RPC_STATUS RPC_ENTRY
  922. THUNK_FN(RpcBindingSetAuthInfo)(
  923. IN RPC_BINDING_HANDLE Binding,
  924. IN THUNK_CHAR *ServerPrincName,
  925. IN unsigned long AuthnLevel,
  926. IN unsigned long AuthnSvc,
  927. IN RPC_AUTH_IDENTITY_HANDLE AuthIdentity, OPTIONAL
  928. IN unsigned long AuthzSvc
  929. )
  930. {
  931. return ( THUNK_FN(RpcBindingSetAuthInfoEx)(
  932. Binding,
  933. ServerPrincName,
  934. AuthnLevel,
  935. AuthnSvc,
  936. AuthIdentity,
  937. AuthzSvc,
  938. 0
  939. ) );
  940. }
  941. RPC_STATUS RPC_ENTRY
  942. THUNK_FN(RpcBindingSetAuthInfoEx) (
  943. IN RPC_BINDING_HANDLE Binding,
  944. IN THUNK_CHAR *ServerPrincName,
  945. IN unsigned long AuthnLevel,
  946. IN unsigned long AuthnSvc,
  947. IN RPC_AUTH_IDENTITY_HANDLE AuthIdentity, OPTIONAL
  948. IN unsigned long AuthzSvc,
  949. IN RPC_SECURITY_QOS * SecurityQOS
  950. )
  951. /*++
  952. Routine Description:
  953. This routine is the ansi thunk for RpcBindingSetAuthInfoW.
  954. Return Value:
  955. RPC_S_OUT_OF_MEMORY - We will return this value if we do not have
  956. enough memory to convert the ansi server principal name into
  957. a unicode string.
  958. --*/
  959. {
  960. USES_CONVERSION;
  961. CHeapInThunk thunkedServerPrincName;
  962. RPC_STATUS RpcStatus;
  963. RPC_HTTP_TRANSPORT_CREDENTIALS_A *HttpCredentials;
  964. ULONG AdditionalTransportCredentialsType;
  965. RPC_SECURITY_QOS_V3_W SecurityQOS3;
  966. RPC_SECURITY_QOS_V3_W *SecurityQOSToUse;
  967. ATTEMPT_HEAP_IN_THUNK(thunkedServerPrincName, ServerPrincName);
  968. if (SecurityQOS)
  969. {
  970. if (SecurityQOS->Version == RPC_C_SECURITY_QOS_VERSION_1)
  971. {
  972. RpcpMemoryCopy(&SecurityQOS3, SecurityQOS, sizeof(RPC_SECURITY_QOS));
  973. SecurityQOS3.AdditionalSecurityInfoType = 0;
  974. SecurityQOS3.u.HttpCredentials = NULL;
  975. SecurityQOS3.Sid = NULL;
  976. }
  977. else
  978. {
  979. RpcpMemoryCopy(&SecurityQOS3, SecurityQOS, sizeof(RPC_SECURITY_QOS_V3_A));
  980. AdditionalTransportCredentialsType = ((RPC_SECURITY_QOS_V3 *)SecurityQOS)->AdditionalSecurityInfoType;
  981. HttpCredentials = ((RPC_SECURITY_QOS_V3_A *)SecurityQOS)->u.HttpCredentials;
  982. if (AdditionalTransportCredentialsType != RPC_C_AUTHN_INFO_TYPE_HTTP)
  983. {
  984. if (AdditionalTransportCredentialsType != 0)
  985. return(RPC_S_INVALID_ARG);
  986. if (HttpCredentials != NULL)
  987. return(RPC_S_INVALID_ARG);
  988. }
  989. else if (HttpCredentials == NULL)
  990. return(RPC_S_INVALID_ARG);
  991. else
  992. {
  993. if (HttpCredentials->TransportCredentials)
  994. {
  995. if (HttpCredentials->TransportCredentials->User)
  996. {
  997. if (RpcpStringLengthA((const char *)HttpCredentials->TransportCredentials->User)
  998. != HttpCredentials->TransportCredentials->UserLength)
  999. {
  1000. return(RPC_S_INVALID_ARG);
  1001. }
  1002. }
  1003. else if (HttpCredentials->TransportCredentials->UserLength)
  1004. return(RPC_S_INVALID_ARG);
  1005. if (HttpCredentials->TransportCredentials->Domain)
  1006. {
  1007. if (RpcpStringLengthA((const char *)HttpCredentials->TransportCredentials->Domain)
  1008. != HttpCredentials->TransportCredentials->DomainLength)
  1009. {
  1010. return(RPC_S_INVALID_ARG);
  1011. }
  1012. }
  1013. else if (HttpCredentials->TransportCredentials->DomainLength)
  1014. return(RPC_S_INVALID_ARG);
  1015. if (HttpCredentials->TransportCredentials->Password)
  1016. {
  1017. if (RpcpStringLengthA((const char *)HttpCredentials->TransportCredentials->Password)
  1018. != HttpCredentials->TransportCredentials->PasswordLength)
  1019. {
  1020. return(RPC_S_INVALID_ARG);
  1021. }
  1022. }
  1023. else if (HttpCredentials->TransportCredentials->PasswordLength)
  1024. return(RPC_S_INVALID_ARG);
  1025. if (HttpCredentials->TransportCredentials->Flags != SEC_WINNT_AUTH_IDENTITY_ANSI)
  1026. return(RPC_S_INVALID_ARG);
  1027. }
  1028. // if you don't want to authenticate against anyone, you can't authenticate
  1029. if (HttpCredentials->AuthenticationTarget == 0)
  1030. return(RPC_S_INVALID_ARG);
  1031. // if you don't support any method of authentication, you can't authenticate
  1032. if (HttpCredentials->NumberOfAuthnSchemes == 0)
  1033. return(RPC_S_INVALID_ARG);
  1034. // if you don't support any method of authentication, you can't authenticate
  1035. if (HttpCredentials->AuthnSchemes == NULL)
  1036. return(RPC_S_INVALID_ARG);
  1037. SecurityQOS3.u.HttpCredentials = ConvertToUnicodeHttpTransportCredentials (
  1038. HttpCredentials);
  1039. if (SecurityQOS3.u.HttpCredentials == NULL)
  1040. return RPC_S_OUT_OF_MEMORY;
  1041. }
  1042. if (SecurityQOS->Version == RPC_C_SECURITY_QOS_VERSION_3)
  1043. {
  1044. SecurityQOS3.Sid = ((RPC_SECURITY_QOS_V3 *)SecurityQOS)->Sid;
  1045. }
  1046. else
  1047. {
  1048. SecurityQOS3.Version = RPC_C_SECURITY_QOS_VERSION_3;
  1049. SecurityQOS3.Sid = NULL;
  1050. }
  1051. }
  1052. SecurityQOSToUse = &SecurityQOS3;
  1053. }
  1054. else
  1055. {
  1056. SecurityQOSToUse = NULL;
  1057. }
  1058. RpcStatus = RpcBindingSetAuthInfoEx(Binding, thunkedServerPrincName,
  1059. AuthnLevel, AuthnSvc, AuthIdentity, AuthzSvc, (RPC_SECURITY_QOS *)SecurityQOSToUse);
  1060. if (SecurityQOSToUse && (SecurityQOS3.AdditionalSecurityInfoType == RPC_C_AUTHN_INFO_TYPE_HTTP))
  1061. {
  1062. // free the converted credentials
  1063. WipeOutAuthIdentity(SecurityQOS3.u.HttpCredentials->TransportCredentials);
  1064. FreeHttpTransportCredentials(SecurityQOS3.u.HttpCredentials);
  1065. }
  1066. return(RpcStatus);
  1067. }
  1068. RPC_STATUS RPC_ENTRY
  1069. THUNK_FN(RpcMgmtInqServerPrincName) (
  1070. IN RPC_BINDING_HANDLE Binding,
  1071. IN unsigned long AuthnSvc,
  1072. OUT THUNK_CHAR **ServerPrincName
  1073. )
  1074. /*++
  1075. Routine Description:
  1076. This routine is the ansi thunk for RpcMgmtInqServerPrincNameW.
  1077. Return Value:
  1078. RPC_S_OUT_OF_MEMORY - We will return this value if we do not have
  1079. enough memory to convert the unicode server principal name into
  1080. an ansi string.
  1081. --*/
  1082. {
  1083. RPC_STATUS RpcStatus;
  1084. USES_CONVERSION;
  1085. COutDelThunk thunkedServerPrincName;
  1086. RpcStatus = RpcMgmtInqServerPrincName(Binding, AuthnSvc, thunkedServerPrincName);
  1087. if ( RpcStatus != RPC_S_OK )
  1088. {
  1089. return(RpcStatus);
  1090. }
  1091. ATTEMPT_OUT_THUNK(thunkedServerPrincName, ServerPrincName);
  1092. return(RPC_S_OK);
  1093. }
  1094. RPCRTAPI
  1095. RPC_STATUS
  1096. RPC_ENTRY
  1097. THUNK_FN(RpcCertGeneratePrincipalName)(
  1098. PCCERT_CONTEXT Context,
  1099. DWORD Flags,
  1100. OUT THUNK_CHAR **pBuffer
  1101. )
  1102. {
  1103. USES_CONVERSION;
  1104. COutDelThunk thunkedServerPrincName;
  1105. RPC_STATUS Status = RpcCertGeneratePrincipalName( Context,
  1106. Flags,
  1107. thunkedServerPrincName
  1108. );
  1109. if (Status != RPC_S_OK)
  1110. {
  1111. return Status;
  1112. }
  1113. ATTEMPT_OUT_THUNK(thunkedServerPrincName, pBuffer);
  1114. return Status;
  1115. }