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.

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