1460 lines
40 KiB
C++
1460 lines
40 KiB
C++
/*++
|
||
|
||
Copyright (C) Microsoft Corporation, 1991 - 1999
|
||
|
||
Module Name:
|
||
|
||
dceansi.cxx
|
||
|
||
|
||
Abstract:
|
||
|
||
This file contains the ansi (as opposed to unicode) versions of the
|
||
runtime APIs. All of these APIs simply do conversions between ansi
|
||
and unicode, and then call a unicode version of the API to do the
|
||
work.
|
||
|
||
Author:
|
||
|
||
Michael Montague (mikemon) 18-Dec-1991
|
||
|
||
Revision History:
|
||
|
||
--*/
|
||
|
||
#include <precomp.hxx>
|
||
#include <wincrypt.h>
|
||
#include <rpcssl.h>
|
||
#include <CharConv.hxx>
|
||
|
||
|
||
RPC_STATUS
|
||
AnsiToUnicodeString (
|
||
IN unsigned char * String,
|
||
OUT UNICODE_STRING * UnicodeString
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This helper routine is used to convert an ansi string into a unicode
|
||
string.
|
||
|
||
Arguments:
|
||
|
||
String - Supplies the ansi string (actually a zero terminated string)
|
||
to convert into a unicode string.
|
||
|
||
UnicodeString - Returns the unicode string. This string will have
|
||
to be freed using RtlFreeUnicodeString by the caller.
|
||
|
||
Return Value:
|
||
|
||
RPC_S_OK - The ansi string was successfully converted into a unicode
|
||
string.
|
||
|
||
RPC_S_OUT_OF_MEMORY - Insufficient memory is available for the unicode
|
||
string.
|
||
|
||
--*/
|
||
{
|
||
NTSTATUS NtStatus;
|
||
ANSI_STRING AnsiString;
|
||
|
||
RtlInitAnsiString(&AnsiString,(PSZ) String);
|
||
NtStatus = RtlAnsiStringToUnicodeString(UnicodeString,&AnsiString,TRUE);
|
||
if (!NT_SUCCESS(NtStatus))
|
||
return(RPC_S_OUT_OF_MEMORY);
|
||
return(RPC_S_OK);
|
||
}
|
||
|
||
unsigned char *
|
||
UnicodeToAnsiString (
|
||
IN RPC_CHAR * WideCharString,
|
||
OUT RPC_STATUS * RpcStatus
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine will convert a unicode string into an ansi string,
|
||
including allocating memory for the ansi string.
|
||
|
||
Arguments:
|
||
|
||
WideCharString - Supplies the unicode string to be converted into
|
||
an ansi string.
|
||
|
||
RpcStatus - Returns the status of the operation; this will be one
|
||
of the following values.
|
||
|
||
RPC_S_OK - The unicode string has successfully been converted
|
||
into an ansi string.
|
||
|
||
RPC_S_OUT_OF_MEMORY - Insufficient memory is available to allocate
|
||
the ansi string.
|
||
|
||
Return Value:
|
||
|
||
A pointer to the ansi string will be returned.
|
||
|
||
--*/
|
||
{
|
||
NTSTATUS NtStatus;
|
||
UNICODE_STRING UnicodeString;
|
||
ANSI_STRING AnsiString;
|
||
unsigned char * NewString;
|
||
|
||
RtlInitUnicodeString(&UnicodeString,WideCharString);
|
||
NtStatus = RtlUnicodeStringToAnsiString(&AnsiString,&UnicodeString,TRUE);
|
||
if (!NT_SUCCESS(NtStatus))
|
||
{
|
||
*RpcStatus = RPC_S_OUT_OF_MEMORY;
|
||
return(0);
|
||
}
|
||
|
||
NewString = new unsigned char[AnsiString.Length + 1];
|
||
if (NewString == 0)
|
||
{
|
||
RtlFreeAnsiString(&AnsiString);
|
||
*RpcStatus = RPC_S_OUT_OF_MEMORY;
|
||
return(0);
|
||
}
|
||
|
||
memcpy(NewString,AnsiString.Buffer,AnsiString.Length + 1);
|
||
RtlFreeAnsiString(&AnsiString);
|
||
*RpcStatus = RPC_S_OK;
|
||
return(NewString);
|
||
}
|
||
|
||
|
||
RPC_STATUS RPC_ENTRY
|
||
THUNK_FN(RpcBindingFromStringBinding) (
|
||
IN THUNK_CHAR *StringBinding,
|
||
OUT RPC_BINDING_HANDLE PAPI * Binding
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine is the ansi thunk to RpcBindingFromStringBindingW.
|
||
|
||
Return Value:
|
||
|
||
RPC_S_OUT_OF_MEMORY - This value will be returned if there is
|
||
insufficient memory available to allocate the unicode string.
|
||
|
||
--*/
|
||
{
|
||
USES_CONVERSION;
|
||
RPC_STATUS RpcStatus;
|
||
CHeapInThunk thunkStringBinding;
|
||
|
||
ATTEMPT_HEAP_IN_THUNK(thunkStringBinding, StringBinding);
|
||
|
||
RpcStatus = RpcBindingFromStringBinding(thunkStringBinding, Binding);
|
||
|
||
return(RpcStatus);
|
||
}
|
||
|
||
|
||
|
||
RPC_STATUS RPC_ENTRY
|
||
THUNK_FN(RpcBindingToStringBinding) (
|
||
IN RPC_BINDING_HANDLE Binding,
|
||
OUT THUNK_CHAR **StringBinding
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine is the ansi thunk to RpcBindingToStringBindingW.
|
||
|
||
Return Value:
|
||
|
||
RPC_S_OUT_OF_MEMORY - We will return this value if we do not
|
||
have enough memory to convert the unicode string binding
|
||
into an ansi string binding.
|
||
|
||
--*/
|
||
{
|
||
RPC_STATUS RpcStatus;
|
||
COutDelThunk thunkStringBinding;
|
||
USES_CONVERSION;
|
||
|
||
RpcStatus = RpcBindingToStringBinding(Binding, thunkStringBinding);
|
||
if (RpcStatus != RPC_S_OK)
|
||
return(RpcStatus);
|
||
|
||
ATTEMPT_OUT_THUNK(thunkStringBinding, StringBinding);
|
||
|
||
return(RpcStatus);
|
||
}
|
||
|
||
/*
|
||
|
||
static RPC_STATUS
|
||
AnsiToUnicodeStringOptional (
|
||
IN unsigned char * String OPTIONAL,
|
||
OUT UNICODE_STRING * UnicodeString
|
||
)
|
||
++
|
||
|
||
Routine Description:
|
||
|
||
This routine is just the same as AnsiToUnicodeString, except that the
|
||
ansi string is optional. If no string is specified, then the buffer
|
||
of the unicode string is set to zero.
|
||
|
||
Arguments:
|
||
|
||
String - Optionally supplies an ansi string to convert to a unicode
|
||
string.
|
||
|
||
UnicodeString - Returns the converted unicode string.
|
||
|
||
Return Value:
|
||
|
||
RPC_S_OK - The ansi string was successfully converted into a unicode
|
||
string.
|
||
|
||
RPC_S_OUT_OF_MEMORY - Insufficient memory is available for the unicode
|
||
string.
|
||
--
|
||
{
|
||
if (ARGUMENT_PRESENT(String))
|
||
return(AnsiToUnicodeString(String,UnicodeString));
|
||
UnicodeString->Buffer = 0;
|
||
return(RPC_S_OK);
|
||
}
|
||
*/
|
||
|
||
|
||
RPC_STATUS RPC_ENTRY
|
||
THUNK_FN(RpcStringBindingCompose) (
|
||
IN THUNK_CHAR *ObjUuid OPTIONAL,
|
||
IN THUNK_CHAR *Protseq OPTIONAL,
|
||
IN THUNK_CHAR *NetworkAddr OPTIONAL,
|
||
IN THUNK_CHAR *Endpoint OPTIONAL,
|
||
IN THUNK_CHAR *Options OPTIONAL,
|
||
OUT THUNK_CHAR **StringBinding OPTIONAL
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine is the ansi thunk to RpcStringBindingComposeW.
|
||
|
||
Return Value:
|
||
|
||
RPC_S_OUT_OF_MEMORY - If insufficient memory is available to
|
||
convert unicode string into ansi strings (and back again),
|
||
we will return this value.
|
||
|
||
--*/
|
||
{
|
||
USES_CONVERSION;
|
||
CHeapInThunk thunkedObjUuid;
|
||
CStackInThunk thunkedProtseq;
|
||
CHeapInThunk thunkedNetworkAddr;
|
||
CHeapInThunk thunkedEndpoint;
|
||
CHeapInThunk thunkedOptions;
|
||
COutDelThunk thunkedStringBinding;
|
||
RPC_STATUS RpcStatus;
|
||
|
||
ATTEMPT_HEAP_IN_THUNK_OPTIONAL(thunkedObjUuid, ObjUuid);
|
||
ATTEMPT_STACK_IN_THUNK_OPTIONAL(thunkedProtseq, Protseq);
|
||
ATTEMPT_HEAP_IN_THUNK_OPTIONAL(thunkedNetworkAddr, NetworkAddr);
|
||
ATTEMPT_HEAP_IN_THUNK_OPTIONAL(thunkedEndpoint, Endpoint);
|
||
ATTEMPT_HEAP_IN_THUNK_OPTIONAL(thunkedOptions, Options);
|
||
|
||
RpcStatus = RpcStringBindingCompose(thunkedObjUuid, thunkedProtseq,
|
||
thunkedNetworkAddr, thunkedEndpoint, thunkedOptions,
|
||
thunkedStringBinding);
|
||
|
||
if (RpcStatus != RPC_S_OK)
|
||
return(RpcStatus);
|
||
|
||
if (ARGUMENT_PRESENT(StringBinding))
|
||
{
|
||
ATTEMPT_OUT_THUNK(thunkedStringBinding, StringBinding);
|
||
}
|
||
return(RpcStatus);
|
||
}
|
||
|
||
|
||
RPC_STATUS RPC_ENTRY
|
||
THUNK_FN(RpcStringBindingParse) (
|
||
IN THUNK_CHAR * StringBinding,
|
||
OUT THUNK_CHAR **ObjUuid OPTIONAL,
|
||
OUT THUNK_CHAR **Protseq OPTIONAL,
|
||
OUT THUNK_CHAR **NetworkAddr OPTIONAL,
|
||
OUT THUNK_CHAR **Endpoint OPTIONAL,
|
||
OUT THUNK_CHAR **NetworkOptions OPTIONAL
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine is the ansi thunk to RpcStringBindingParseW.
|
||
|
||
Return Value:
|
||
|
||
RPC_S_OUT_OF_MEMORY - This will be returned if insufficient memory
|
||
is available to convert the strings to and from unicode.
|
||
|
||
--*/
|
||
{
|
||
USES_CONVERSION;
|
||
CHeapInThunk thunkedStringBinding;
|
||
COutDelThunk thunkedObjUuid;
|
||
COutDelThunk thunkedProtseq;
|
||
COutDelThunk thunkedNetworkAddr;
|
||
COutDelThunk thunkedEndpoint;
|
||
COutDelThunk thunkedNetworkOptions;
|
||
RPC_STATUS RpcStatus;
|
||
|
||
ATTEMPT_HEAP_IN_THUNK(thunkedStringBinding, StringBinding);
|
||
|
||
RpcStatus = RpcStringBindingParse(thunkedStringBinding,
|
||
thunkedObjUuid, thunkedProtseq, thunkedNetworkAddr,
|
||
thunkedEndpoint, thunkedNetworkOptions);
|
||
|
||
if (RpcStatus != RPC_S_OK)
|
||
return(RpcStatus);
|
||
|
||
if (ARGUMENT_PRESENT(Protseq))
|
||
*Protseq = 0;
|
||
|
||
if (ARGUMENT_PRESENT(NetworkAddr))
|
||
*NetworkAddr = 0;
|
||
|
||
if (ARGUMENT_PRESENT(Endpoint))
|
||
*Endpoint = 0;
|
||
|
||
if (ARGUMENT_PRESENT(NetworkOptions))
|
||
*NetworkOptions = 0;
|
||
|
||
if (ARGUMENT_PRESENT(ObjUuid))
|
||
{
|
||
RpcStatus = thunkedObjUuid.Convert();
|
||
if (RpcStatus != RPC_S_OK)
|
||
goto DeleteStringsAndReturn;
|
||
*ObjUuid = thunkedObjUuid;
|
||
}
|
||
|
||
if (ARGUMENT_PRESENT(Protseq))
|
||
{
|
||
RpcStatus = thunkedProtseq.Convert();
|
||
if (RpcStatus != RPC_S_OK)
|
||
goto DeleteStringsAndReturn;
|
||
*Protseq = thunkedProtseq;
|
||
}
|
||
|
||
if (ARGUMENT_PRESENT(NetworkAddr))
|
||
{
|
||
RpcStatus = thunkedNetworkAddr.Convert();
|
||
if (RpcStatus != RPC_S_OK)
|
||
goto DeleteStringsAndReturn;
|
||
*NetworkAddr = thunkedNetworkAddr;
|
||
}
|
||
|
||
if (ARGUMENT_PRESENT(Endpoint))
|
||
{
|
||
RpcStatus = thunkedEndpoint.Convert();
|
||
if (RpcStatus != RPC_S_OK)
|
||
goto DeleteStringsAndReturn;
|
||
*Endpoint = thunkedEndpoint;
|
||
}
|
||
|
||
if (ARGUMENT_PRESENT(NetworkOptions))
|
||
{
|
||
RpcStatus = thunkedNetworkOptions.Convert();
|
||
if (RpcStatus != RPC_S_OK)
|
||
goto DeleteStringsAndReturn;
|
||
*NetworkOptions = thunkedNetworkOptions;
|
||
}
|
||
|
||
|
||
DeleteStringsAndReturn:
|
||
|
||
if (RpcStatus != RPC_S_OK)
|
||
{
|
||
if (ARGUMENT_PRESENT(Protseq))
|
||
{
|
||
delete *Protseq;
|
||
*Protseq = 0;
|
||
}
|
||
|
||
if (ARGUMENT_PRESENT(NetworkAddr))
|
||
{
|
||
delete *NetworkAddr;
|
||
*NetworkAddr = 0;
|
||
}
|
||
|
||
if (ARGUMENT_PRESENT(Endpoint))
|
||
{
|
||
delete *Endpoint;
|
||
*Endpoint = 0;
|
||
}
|
||
|
||
if (ARGUMENT_PRESENT(NetworkOptions))
|
||
{
|
||
delete *NetworkOptions;
|
||
*NetworkOptions = 0;
|
||
}
|
||
}
|
||
|
||
return(RpcStatus);
|
||
}
|
||
|
||
|
||
RPC_STATUS RPC_ENTRY
|
||
THUNK_FN(RpcNetworkIsProtseqValid) (
|
||
IN THUNK_CHAR *Protseq
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine is the ansi thunk to RpcNetworkIsProtseqValidW.
|
||
|
||
Return Value:
|
||
|
||
RPC_S_OUT_OF_MEMORY - We will return this value if we run out of
|
||
memory trying to allocate space for the string.
|
||
|
||
--*/
|
||
{
|
||
USES_CONVERSION;
|
||
CStackInThunk thunkedProtseq;
|
||
RPC_STATUS RpcStatus;
|
||
|
||
ATTEMPT_STACK_IN_THUNK(thunkedProtseq, Protseq);
|
||
|
||
RpcStatus = RpcNetworkIsProtseqValid(thunkedProtseq);
|
||
|
||
return(RpcStatus);
|
||
}
|
||
|
||
|
||
RPC_STATUS RPC_ENTRY
|
||
THUNK_FN(RpcNetworkInqProtseqs) (
|
||
#ifdef UNICODE
|
||
OUT RPC_PROTSEQ_VECTORA PAPI * PAPI * ProtseqVector
|
||
#else
|
||
OUT RPC_PROTSEQ_VECTORW PAPI * PAPI * ProtseqVector
|
||
#endif
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine is the ansi thunk for RpcNetworkInqProtseqsW.
|
||
|
||
Return Value:
|
||
|
||
RPC_S_OUT_OF_MEMORY - Insufficient memory is available to convert
|
||
the rpc protocol sequences from unicode into ansi.
|
||
|
||
--*/
|
||
{
|
||
RPC_STATUS RpcStatus;
|
||
RPC_CHAR *pString;
|
||
unsigned int Index, Count;
|
||
|
||
RpcStatus = RpcNetworkInqProtseqs(
|
||
(RPC_PROTSEQ_VECTOR **) ProtseqVector);
|
||
if (RpcStatus != RPC_S_OK)
|
||
return(RpcStatus);
|
||
|
||
for (Index = 0, Count = (*ProtseqVector)->Count; Index < Count; Index++)
|
||
{
|
||
pString = (RPC_CHAR *) (*ProtseqVector)->Protseq[Index];
|
||
#ifdef UNICODE
|
||
RpcStatus = W2AAttachHelper(pString, (char **) &((*ProtseqVector)->Protseq[Index]));
|
||
#else
|
||
RpcStatus = A2WAttachHelper((char *) pString, &((*ProtseqVector)->Protseq[Index]));
|
||
#endif
|
||
delete pString;
|
||
if (RpcStatus != RPC_S_OK)
|
||
{
|
||
#ifdef UNICODE
|
||
RpcProtseqVectorFreeA(ProtseqVector);
|
||
#else
|
||
RpcProtseqVectorFreeW(ProtseqVector);
|
||
#endif
|
||
return(RpcStatus);
|
||
}
|
||
}
|
||
|
||
return(RPC_S_OK);
|
||
}
|
||
|
||
|
||
RPC_STATUS RPC_ENTRY
|
||
THUNK_FN(RpcProtseqVectorFree) (
|
||
#ifdef UNICODE
|
||
IN OUT RPC_PROTSEQ_VECTORA PAPI * PAPI * ProtseqVector
|
||
#else
|
||
IN OUT RPC_PROTSEQ_VECTORW PAPI * PAPI * ProtseqVector
|
||
#endif
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine is the ansi thunk for RpcProtseqVectorFreeW.
|
||
|
||
--*/
|
||
{
|
||
return(RpcProtseqVectorFree((RPC_PROTSEQ_VECTOR **) ProtseqVector));
|
||
}
|
||
|
||
|
||
RPC_STATUS RPC_ENTRY
|
||
THUNK_FN(I_RpcServerUseProtseq2) (
|
||
IN THUNK_CHAR * NetworkAddress,
|
||
IN THUNK_CHAR * Protseq,
|
||
IN unsigned int MaxCalls,
|
||
IN void PAPI * SecurityDescriptor,
|
||
IN void * pPolicy
|
||
)
|
||
{
|
||
USES_CONVERSION;
|
||
CStackInThunk thunkProtseq;
|
||
CHeapInThunk thunkNetworkAddress;
|
||
RPC_STATUS RpcStatus;
|
||
PRPC_POLICY Policy = (PRPC_POLICY) pPolicy;
|
||
|
||
ATTEMPT_STACK_IN_THUNK(thunkProtseq, Protseq);
|
||
ATTEMPT_HEAP_IN_THUNK_OPTIONAL(thunkNetworkAddress, NetworkAddress);
|
||
|
||
RpcStatus = I_RpcServerUseProtseq2(thunkNetworkAddress, thunkProtseq, MaxCalls,
|
||
SecurityDescriptor, (void *) Policy);
|
||
|
||
return(RpcStatus);
|
||
}
|
||
|
||
|
||
|
||
RPC_STATUS RPC_ENTRY
|
||
THUNK_FN(RpcServerUseProtseqEx) (
|
||
IN THUNK_CHAR *Protseq,
|
||
IN unsigned int MaxCalls,
|
||
IN void PAPI * SecurityDescriptor,
|
||
IN PRPC_POLICY Policy
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This is the ansi thunk to RpcServerUseProtseqW.
|
||
|
||
Return Value:
|
||
|
||
RPC_S_OUT_OF_MEMORY - If we do not have enough memory to convert
|
||
the ansi strings into unicode strings, this value will be returned.
|
||
|
||
--*/
|
||
{
|
||
return THUNK_FN(I_RpcServerUseProtseq2) (NULL, Protseq, MaxCalls, SecurityDescriptor, (void *) Policy) ;
|
||
}
|
||
|
||
|
||
RPC_STATUS RPC_ENTRY
|
||
THUNK_FN(RpcServerUseProtseq) (
|
||
IN THUNK_CHAR *Protseq,
|
||
IN unsigned int MaxCalls,
|
||
IN void PAPI * SecurityDescriptor OPTIONAL
|
||
)
|
||
{
|
||
RPC_POLICY Policy ;
|
||
|
||
Policy.Length = sizeof(RPC_POLICY) ;
|
||
Policy.EndpointFlags = 0;
|
||
Policy.NICFlags = 0;
|
||
|
||
return THUNK_FN(I_RpcServerUseProtseq2) (NULL, Protseq, MaxCalls, SecurityDescriptor, (void *) &Policy) ;
|
||
}
|
||
|
||
|
||
RPC_STATUS RPC_ENTRY
|
||
THUNK_FN(I_RpcServerUseProtseqEp2) (
|
||
IN THUNK_CHAR * NetworkAddress,
|
||
IN THUNK_CHAR *Protseq,
|
||
IN unsigned int MaxCalls,
|
||
IN THUNK_CHAR *Endpoint,
|
||
IN void PAPI * SecurityDescriptor,
|
||
IN void * pPolicy
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This is the ansi thunk to RpcServerUseProtseqEpW.
|
||
|
||
Return Value:
|
||
|
||
RPC_S_OUT_OF_MEMORY - If we do not have enough memory to convert
|
||
the ansi strings into unicode strings, this value will be returned.
|
||
|
||
--*/
|
||
{
|
||
USES_CONVERSION;
|
||
CStackInThunk thunkedProtseq;
|
||
CHeapInThunk thunkedEndpoint;
|
||
CHeapInThunk thunkedNetworkAddress;
|
||
PRPC_POLICY Policy = (PRPC_POLICY) pPolicy;
|
||
|
||
ATTEMPT_STACK_IN_THUNK(thunkedProtseq, Protseq);
|
||
ATTEMPT_HEAP_IN_THUNK(thunkedEndpoint, Endpoint);
|
||
ATTEMPT_HEAP_IN_THUNK_OPTIONAL(thunkedNetworkAddress, NetworkAddress);
|
||
|
||
return (I_RpcServerUseProtseqEp2(thunkedNetworkAddress, thunkedProtseq, MaxCalls,
|
||
thunkedEndpoint, SecurityDescriptor,
|
||
(void *) Policy));
|
||
}
|
||
|
||
|
||
RPC_STATUS RPC_ENTRY
|
||
THUNK_FN(RpcServerUseProtseqEpEx) (
|
||
IN THUNK_CHAR *Protseq,
|
||
IN unsigned int MaxCalls,
|
||
IN THUNK_CHAR *Endpoint,
|
||
IN void PAPI * SecurityDescriptor,
|
||
IN PRPC_POLICY Policy
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This is the ansi thunk to RpcServerUseProtseqEpW.
|
||
|
||
Return Value:
|
||
|
||
RPC_S_OUT_OF_MEMORY - If we do not have enough memory to convert
|
||
the ansi strings into unicode strings, this value will be returned.
|
||
|
||
--*/
|
||
{
|
||
return THUNK_FN(I_RpcServerUseProtseqEp2) (NULL, Protseq, MaxCalls, Endpoint,
|
||
SecurityDescriptor, (void *) Policy) ;
|
||
}
|
||
|
||
|
||
|
||
|
||
RPC_STATUS RPC_ENTRY
|
||
THUNK_FN(RpcServerUseProtseqEp) (
|
||
IN THUNK_CHAR *Protseq,
|
||
IN unsigned int MaxCalls,
|
||
IN THUNK_CHAR *Endpoint,
|
||
IN void PAPI * SecurityDescriptor
|
||
)
|
||
{
|
||
RPC_POLICY Policy ;
|
||
|
||
Policy.Length = sizeof(RPC_POLICY) ;
|
||
Policy.EndpointFlags = 0;
|
||
Policy.NICFlags = 0;
|
||
|
||
return THUNK_FN(I_RpcServerUseProtseqEp2) (NULL, Protseq, MaxCalls, Endpoint,
|
||
SecurityDescriptor, (void *) &Policy) ;
|
||
}
|
||
|
||
|
||
RPC_STATUS RPC_ENTRY
|
||
THUNK_FN(RpcServerUseProtseqIfEx) (
|
||
IN THUNK_CHAR *Protseq,
|
||
IN unsigned int MaxCalls,
|
||
IN RPC_IF_HANDLE IfSpec,
|
||
IN void PAPI * SecurityDescriptor,
|
||
IN PRPC_POLICY Policy
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This is the ansi thunk to RpcServerUseProtseqIfW.
|
||
|
||
Return Value:
|
||
|
||
RPC_S_OUT_OF_MEMORY - If we do not have enough memory to convert
|
||
the ansi strings into unicode strings, this value will be returned.
|
||
|
||
--*/
|
||
{
|
||
USES_CONVERSION;
|
||
CStackInThunk thunkedProtseq;
|
||
|
||
ATTEMPT_STACK_IN_THUNK(thunkedProtseq, Protseq);
|
||
|
||
return (RpcServerUseProtseqIfEx(thunkedProtseq, MaxCalls,
|
||
IfSpec, SecurityDescriptor, Policy));
|
||
}
|
||
|
||
|
||
RPC_STATUS RPC_ENTRY
|
||
THUNK_FN(RpcServerUseProtseqIf) (
|
||
IN THUNK_CHAR *Protseq,
|
||
IN unsigned int MaxCalls,
|
||
IN RPC_IF_HANDLE IfSpec,
|
||
IN void PAPI * SecurityDescriptor
|
||
)
|
||
{
|
||
RPC_POLICY Policy ;
|
||
|
||
Policy.Length = sizeof(RPC_POLICY) ;
|
||
Policy.EndpointFlags = 0;
|
||
Policy.NICFlags = 0;
|
||
|
||
return THUNK_FN(RpcServerUseProtseqIfEx) ( Protseq, MaxCalls, IfSpec,
|
||
SecurityDescriptor, &Policy) ;
|
||
}
|
||
|
||
|
||
RPC_STATUS RPC_ENTRY
|
||
THUNK_FN(RpcNsBindingInqEntryName) (
|
||
IN RPC_BINDING_HANDLE Binding,
|
||
IN unsigned long EntryNameSyntax,
|
||
OUT THUNK_CHAR **EntryName
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine is the ansi thunk to RpcNsBindingInqEntryNameW.
|
||
|
||
Return Value:
|
||
|
||
RPC_S_OUT_OF_MEMORY - We will return this value if we do not
|
||
have enough memory to convert the unicode entry name into
|
||
an ansi entry name.
|
||
|
||
--*/
|
||
{
|
||
RPC_STATUS RpcStatus;
|
||
USES_CONVERSION;
|
||
COutDelThunk thunkedEntryName;
|
||
|
||
RpcStatus = RpcNsBindingInqEntryName(Binding, EntryNameSyntax,
|
||
thunkedEntryName);
|
||
|
||
if ( RpcStatus == RPC_S_NO_ENTRY_NAME )
|
||
{
|
||
ATTEMPT_OUT_THUNK(thunkedEntryName, EntryName);
|
||
return(RPC_S_NO_ENTRY_NAME);
|
||
}
|
||
|
||
if ( RpcStatus != RPC_S_OK )
|
||
{
|
||
return(RpcStatus);
|
||
}
|
||
|
||
ATTEMPT_OUT_THUNK(thunkedEntryName, EntryName);
|
||
return(RPC_S_OK);
|
||
}
|
||
|
||
|
||
RPC_STATUS RPC_ENTRY
|
||
THUNK_FN(UuidToString) (
|
||
IN UUID PAPI * Uuid,
|
||
OUT THUNK_CHAR **StringUuid
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine converts a UUID into its string representation.
|
||
|
||
Arguments:
|
||
|
||
Uuid - Supplies the UUID to be converted into string representation.
|
||
|
||
StringUuid - Returns the string representation of the UUID. The
|
||
runtime will allocate the string. The caller is responsible for
|
||
freeing the string using RpcStringFree.
|
||
|
||
Return Value:
|
||
|
||
RPC_S_OK - We successfully converted the UUID into its string
|
||
representation.
|
||
|
||
RPC_S_OUT_OF_MEMORY - Insufficient memory is available to allocate
|
||
a string.
|
||
|
||
--*/
|
||
{
|
||
// The string representation of a UUID is always 36 character long,
|
||
// and we need one more for the terminating zero.
|
||
|
||
RPC_CHAR String[37];
|
||
RPC_STATUS RpcStatus;
|
||
|
||
InitializeIfNecessary();
|
||
|
||
((RPC_UUID PAPI *) Uuid)->ConvertToString(String);
|
||
String[36] = 0;
|
||
#ifdef UNICODE
|
||
return W2AAttachHelper(String, (char **)StringUuid);
|
||
#else
|
||
return A2WAttachHelper((char *)String, StringUuid);
|
||
#endif
|
||
}
|
||
|
||
|
||
RPC_STATUS RPC_ENTRY
|
||
THUNK_FN(UuidFromString) (
|
||
IN THUNK_CHAR *StringUuid OPTIONAL,
|
||
OUT UUID PAPI * Uuid
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
We convert a UUID from its string representation into the binary
|
||
representation.
|
||
|
||
Arguments:
|
||
|
||
StringUuid - Optionally supplies the string representation of the UUID;
|
||
if this argument is not supplied, then the NIL UUID is returned.
|
||
|
||
Uuid - Returns the binary representation of the UUID.
|
||
|
||
Return Value:
|
||
|
||
RPC_S_OK - The string representation was successfully converted into
|
||
the binary representation.
|
||
|
||
RPC_S_INVALID_STRING_UUID - The supplied string UUID is not correct.
|
||
|
||
RPC_S_OUT_OF_MEMORY - Insufficient memory is available to convert the
|
||
ansi string into a unicode string.
|
||
|
||
--*/
|
||
{
|
||
RPC_UUID RpcUuid;
|
||
RPC_STATUS RpcStatus;
|
||
USES_CONVERSION;
|
||
CHeapInThunk thunkedStringUuid;
|
||
|
||
if ( StringUuid == 0 )
|
||
{
|
||
((RPC_UUID PAPI *) Uuid)->SetToNullUuid();
|
||
return(RPC_S_OK);
|
||
}
|
||
|
||
ATTEMPT_HEAP_IN_THUNK(thunkedStringUuid, StringUuid);
|
||
|
||
if (RpcUuid.ConvertFromString(thunkedStringUuid) != 0)
|
||
{
|
||
return(RPC_S_INVALID_STRING_UUID);
|
||
}
|
||
((RPC_UUID PAPI *) Uuid)->CopyUuid(&RpcUuid);
|
||
return(RPC_S_OK);
|
||
}
|
||
|
||
|
||
RPC_STATUS RPC_ENTRY
|
||
THUNK_FN(RpcServerRegisterAuthInfo) (
|
||
IN THUNK_CHAR *ServerPrincName,
|
||
IN unsigned long AuthnSvc,
|
||
IN RPC_AUTH_KEY_RETRIEVAL_FN GetKeyFn OPTIONAL,
|
||
IN void PAPI * Arg OPTIONAL
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine is the ansi thunk to RpcServerRegisterAuthInfoW.
|
||
|
||
Return Value:
|
||
|
||
RPC_S_OUT_OF_MEMORY - We will return this value if we do not have
|
||
enough memory to convert the ansi server principal name into
|
||
a unicode string.
|
||
|
||
--*/
|
||
{
|
||
USES_CONVERSION;
|
||
CHeapInThunk thunkedServerPrincName;
|
||
RPC_STATUS RpcStatus;
|
||
|
||
ATTEMPT_HEAP_IN_THUNK(thunkedServerPrincName, ServerPrincName);
|
||
|
||
RpcStatus = RpcServerRegisterAuthInfo(thunkedServerPrincName, AuthnSvc,
|
||
GetKeyFn, Arg);
|
||
|
||
return(RpcStatus);
|
||
}
|
||
|
||
RPC_STATUS RPC_ENTRY
|
||
THUNK_FN(RpcBindingInqAuthClient) (
|
||
IN RPC_BINDING_HANDLE ClientBinding, OPTIONAL
|
||
OUT RPC_AUTHZ_HANDLE PAPI * Privs,
|
||
OUT THUNK_CHAR **PrincName, OPTIONAL
|
||
OUT unsigned long PAPI * AuthnLevel, OPTIONAL
|
||
OUT unsigned long PAPI * AuthnSvc, OPTIONAL
|
||
OUT unsigned long PAPI * AuthzSvc OPTIONAL
|
||
)
|
||
{
|
||
return THUNK_FN(RpcBindingInqAuthClientEx)( ClientBinding,
|
||
Privs,
|
||
PrincName,
|
||
AuthnLevel,
|
||
AuthnSvc,
|
||
AuthzSvc,
|
||
0
|
||
);
|
||
}
|
||
|
||
|
||
RPC_STATUS RPC_ENTRY
|
||
THUNK_FN(RpcBindingInqAuthClientEx) (
|
||
IN RPC_BINDING_HANDLE ClientBinding, OPTIONAL
|
||
OUT RPC_AUTHZ_HANDLE PAPI * Privs,
|
||
OUT THUNK_CHAR **ServerPrincName, OPTIONAL
|
||
OUT unsigned long PAPI * AuthnLevel, OPTIONAL
|
||
OUT unsigned long PAPI * AuthnSvc, OPTIONAL
|
||
OUT unsigned long PAPI * AuthzSvc, OPTIONAL
|
||
IN unsigned long Flags
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine is the ansi thunk for RpcBindingInqAuthClientW.
|
||
|
||
Return Value:
|
||
|
||
RPC_S_OUT_OF_MEMORY - If we can not allocate space to convert the
|
||
unicode server principal name into unicode, we will return this
|
||
value.
|
||
|
||
--*/
|
||
{
|
||
RPC_STATUS RpcStatus;
|
||
USES_CONVERSION;
|
||
COutDelThunk thunkedServerPrincName;
|
||
|
||
RpcStatus = RpcBindingInqAuthClientEx(ClientBinding,
|
||
Privs,
|
||
(ARGUMENT_PRESENT(ServerPrincName) ? (RPC_CHAR **)thunkedServerPrincName : 0),
|
||
AuthnLevel,
|
||
AuthnSvc,
|
||
AuthzSvc,
|
||
Flags);
|
||
|
||
if ( RpcStatus != RPC_S_OK )
|
||
{
|
||
return(RpcStatus);
|
||
}
|
||
|
||
if (ARGUMENT_PRESENT(ServerPrincName))
|
||
{
|
||
ATTEMPT_OUT_THUNK_OPTIONAL(thunkedServerPrincName, ServerPrincName);
|
||
}
|
||
return(RpcStatus);
|
||
}
|
||
|
||
RPC_STATUS RPC_ENTRY
|
||
THUNK_FN(RpcServerInqCallAttributes) (
|
||
IN RPC_BINDING_HANDLE ClientBinding, OPTIONAL
|
||
IN OUT void *RpcCallAttributes
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine is the ansi thunk for RpcServerInqCallAttributes.
|
||
|
||
Return Value:
|
||
|
||
RPC_S_OUT_OF_MEMORY - If we can not allocate space to convert the
|
||
unicode server principal name into unicode, we will return this
|
||
value.
|
||
The API can in addition return all errors returned by the Unicode
|
||
version.
|
||
|
||
--*/
|
||
{
|
||
RPC_STATUS RpcStatus;
|
||
USES_CONVERSION;
|
||
COutDelThunk thunkedServerPrincName;
|
||
RPC_CALL_ATTRIBUTES_V1_W *CallAttributesW;
|
||
RPC_CALL_ATTRIBUTES_V1_A *CallAttributesA;
|
||
unsigned char *OldClientPrincipalNameBuffer;
|
||
RPC_CHAR *NewClientPrincipalNameBuffer = NULL;
|
||
ULONG OldClientPrincipalNameBufferLength;
|
||
ULONG NewClientPrincipalNameBufferLength;
|
||
unsigned char *OldServerPrincipalNameBuffer;
|
||
RPC_CHAR *NewServerPrincipalNameBuffer = NULL;
|
||
ULONG OldServerPrincipalNameBufferLength;
|
||
ULONG NewServerPrincipalNameBufferLength;
|
||
|
||
// we use the same structure to pass to the unicode API, but
|
||
// we save some data members
|
||
CallAttributesW =
|
||
(RPC_CALL_ATTRIBUTES_V1_W *)RpcCallAttributes;
|
||
CallAttributesA =
|
||
(RPC_CALL_ATTRIBUTES_V1_A *)RpcCallAttributes;
|
||
|
||
if (CallAttributesW->Flags & RPC_QUERY_CLIENT_PRINCIPAL_NAME)
|
||
{
|
||
OldClientPrincipalNameBuffer = CallAttributesA->ClientPrincipalName;
|
||
OldClientPrincipalNameBufferLength = CallAttributesA->ClientPrincipalNameBufferLength;
|
||
if (OldClientPrincipalNameBufferLength != 0)
|
||
{
|
||
NewClientPrincipalNameBuffer = new RPC_CHAR[OldClientPrincipalNameBufferLength];
|
||
if (NewClientPrincipalNameBuffer == NULL)
|
||
{
|
||
return RPC_S_OUT_OF_MEMORY;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// here CallAttributesW->ClientPrincipalName must be NULL. If it's
|
||
// not, the unicode function will return error. Delegate the check to it
|
||
NewClientPrincipalNameBuffer = CallAttributesW->ClientPrincipalName;
|
||
}
|
||
}
|
||
|
||
if (CallAttributesW->Flags & RPC_QUERY_SERVER_PRINCIPAL_NAME)
|
||
{
|
||
OldServerPrincipalNameBuffer = CallAttributesA->ServerPrincipalName;
|
||
OldServerPrincipalNameBufferLength = CallAttributesA->ServerPrincipalNameBufferLength;
|
||
if (OldServerPrincipalNameBufferLength != 0)
|
||
{
|
||
NewServerPrincipalNameBuffer = new RPC_CHAR[OldServerPrincipalNameBufferLength];
|
||
if (NewServerPrincipalNameBuffer == NULL)
|
||
{
|
||
if ((CallAttributesW->Flags & RPC_QUERY_CLIENT_PRINCIPAL_NAME)
|
||
&& (OldClientPrincipalNameBufferLength != 0))
|
||
{
|
||
ASSERT(NewClientPrincipalNameBuffer != NULL);
|
||
delete NewClientPrincipalNameBuffer;
|
||
}
|
||
return RPC_S_OUT_OF_MEMORY;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// here CallAttributesW->ServerPrincipalName must be NULL. If it's
|
||
// not, the unicode function will return error. Delegate the check to it
|
||
NewServerPrincipalNameBuffer = CallAttributesW->ServerPrincipalName;
|
||
}
|
||
}
|
||
|
||
// by now all buffers are allocated, so we don't have failure paths b/n
|
||
// here and the API call
|
||
if (CallAttributesW->Flags & RPC_QUERY_SERVER_PRINCIPAL_NAME)
|
||
{
|
||
CallAttributesW->ServerPrincipalName = NewServerPrincipalNameBuffer;
|
||
CallAttributesW->ServerPrincipalNameBufferLength *= 2;
|
||
}
|
||
|
||
if (CallAttributesW->Flags & RPC_QUERY_CLIENT_PRINCIPAL_NAME)
|
||
{
|
||
CallAttributesW->ClientPrincipalName = NewClientPrincipalNameBuffer;
|
||
CallAttributesW->ClientPrincipalNameBufferLength *= 2;
|
||
}
|
||
|
||
RpcStatus = RpcServerInqCallAttributes(ClientBinding,
|
||
RpcCallAttributes
|
||
);
|
||
|
||
// restore user's values to the structure regardless of failure
|
||
if (CallAttributesW->Flags & RPC_QUERY_CLIENT_PRINCIPAL_NAME)
|
||
{
|
||
NewClientPrincipalNameBufferLength = CallAttributesA->ClientPrincipalNameBufferLength;
|
||
CallAttributesA->ClientPrincipalNameBufferLength = OldClientPrincipalNameBufferLength;
|
||
CallAttributesA->ClientPrincipalName = OldClientPrincipalNameBuffer;
|
||
};
|
||
|
||
if (CallAttributesW->Flags & RPC_QUERY_SERVER_PRINCIPAL_NAME)
|
||
{
|
||
NewServerPrincipalNameBufferLength = CallAttributesA->ServerPrincipalNameBufferLength;
|
||
CallAttributesA->ServerPrincipalNameBufferLength = OldServerPrincipalNameBufferLength;
|
||
CallAttributesA->ServerPrincipalName = OldServerPrincipalNameBuffer;
|
||
};
|
||
|
||
if ((RpcStatus != RPC_S_OK)
|
||
&& (RpcStatus != ERROR_MORE_DATA))
|
||
{
|
||
if ((CallAttributesW->Flags & RPC_QUERY_CLIENT_PRINCIPAL_NAME)
|
||
&& (OldClientPrincipalNameBufferLength != 0))
|
||
{
|
||
ASSERT(NewClientPrincipalNameBuffer != NULL);
|
||
delete NewClientPrincipalNameBuffer;
|
||
}
|
||
|
||
if ((CallAttributesW->Flags & RPC_QUERY_SERVER_PRINCIPAL_NAME)
|
||
&& (OldServerPrincipalNameBufferLength != 0))
|
||
{
|
||
ASSERT(NewServerPrincipalNameBuffer != NULL);
|
||
delete NewServerPrincipalNameBuffer;
|
||
}
|
||
|
||
return(RpcStatus);
|
||
}
|
||
|
||
ASSERT((RpcStatus == RPC_S_OK)
|
||
|| (RpcStatus == ERROR_MORE_DATA));
|
||
|
||
if (CallAttributesW->Flags & RPC_QUERY_SERVER_PRINCIPAL_NAME)
|
||
{
|
||
CallAttributesW->ServerPrincipalNameBufferLength = NewServerPrincipalNameBufferLength >> 1;
|
||
// if we returned non-zero, and there was enough space in the string to start with, we must
|
||
// have returned a string as well
|
||
if ((CallAttributesW->ServerPrincipalNameBufferLength > 0)
|
||
&& (CallAttributesW->ServerPrincipalNameBufferLength <= OldServerPrincipalNameBufferLength))
|
||
{
|
||
RtlUnicodeToMultiByteN((char *)CallAttributesA->ServerPrincipalName,
|
||
CallAttributesA->ServerPrincipalNameBufferLength,
|
||
NULL,
|
||
NewServerPrincipalNameBuffer,
|
||
NewServerPrincipalNameBufferLength);
|
||
}
|
||
}
|
||
|
||
if (CallAttributesW->Flags & RPC_QUERY_CLIENT_PRINCIPAL_NAME)
|
||
{
|
||
CallAttributesW->ClientPrincipalNameBufferLength = NewClientPrincipalNameBufferLength >> 1;
|
||
// if we returned non-zero, and there was enough space in the string to start with, we must
|
||
// have returned a string as well
|
||
if ((CallAttributesW->ClientPrincipalNameBufferLength > 0)
|
||
&& (CallAttributesW->ClientPrincipalNameBufferLength <= OldClientPrincipalNameBufferLength))
|
||
{
|
||
RtlUnicodeToMultiByteN((char *)CallAttributesA->ClientPrincipalName,
|
||
CallAttributesA->ClientPrincipalNameBufferLength,
|
||
NULL,
|
||
NewClientPrincipalNameBuffer,
|
||
NewClientPrincipalNameBufferLength);
|
||
}
|
||
}
|
||
|
||
return(RpcStatus);
|
||
}
|
||
|
||
|
||
RPC_STATUS RPC_ENTRY
|
||
THUNK_FN(RpcBindingInqAuthInfo) (
|
||
IN RPC_BINDING_HANDLE Binding,
|
||
OUT THUNK_CHAR **ServerPrincName, OPTIONAL
|
||
OUT unsigned long PAPI * AuthnLevel, OPTIONAL
|
||
OUT unsigned long PAPI * AuthnSvc, OPTIONAL
|
||
OUT RPC_AUTH_IDENTITY_HANDLE PAPI * AuthIdentity, OPTIONAL
|
||
OUT unsigned long PAPI * AuthzSvc OPTIONAL
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine is the ansi thunk for RpcBindingInqAuthInfoW.
|
||
|
||
Return Value:
|
||
|
||
RPC_S_OUT_OF_MEMORY - If we can not allocate space to convert the
|
||
unicode server principal name into unicode, we will return this
|
||
value.
|
||
|
||
--*/
|
||
{
|
||
RPC_STATUS RpcStatus;
|
||
|
||
return( THUNK_FN(RpcBindingInqAuthInfoEx) (
|
||
Binding,
|
||
ServerPrincName,
|
||
AuthnLevel,
|
||
AuthnSvc,
|
||
AuthIdentity,
|
||
AuthzSvc,
|
||
0,
|
||
0
|
||
) );
|
||
|
||
}
|
||
|
||
|
||
RPC_STATUS RPC_ENTRY
|
||
THUNK_FN(RpcBindingInqAuthInfoEx) (
|
||
IN RPC_BINDING_HANDLE Binding,
|
||
OUT THUNK_CHAR **ServerPrincName, OPTIONAL
|
||
OUT unsigned long PAPI * AuthnLevel, OPTIONAL
|
||
OUT unsigned long PAPI * AuthnSvc, OPTIONAL
|
||
OUT RPC_AUTH_IDENTITY_HANDLE PAPI * AuthIdentity, OPTIONAL
|
||
OUT unsigned long PAPI * AuthzSvc, OPTIONAL
|
||
IN unsigned long RpcSecurityQosVersion,
|
||
OUT RPC_SECURITY_QOS * SecurityQOS
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine is the ansi thunk for RpcBindingInqAuthInfoW.
|
||
|
||
Return Value:
|
||
|
||
RPC_S_OUT_OF_MEMORY - If we can not allocate space to convert the
|
||
unicode server principal name into unicode, we will return this
|
||
value.
|
||
|
||
--*/
|
||
{
|
||
RPC_STATUS RpcStatus;
|
||
USES_CONVERSION;
|
||
COutDelThunk thunkedServerPrincName;
|
||
|
||
RpcStatus = RpcBindingInqAuthInfoEx(
|
||
Binding,
|
||
(ARGUMENT_PRESENT(ServerPrincName) ? (RPC_CHAR **)thunkedServerPrincName : 0),
|
||
AuthnLevel,
|
||
AuthnSvc,
|
||
AuthIdentity,
|
||
AuthzSvc,
|
||
RpcSecurityQosVersion,
|
||
SecurityQOS
|
||
);
|
||
|
||
if ( RpcStatus != RPC_S_OK )
|
||
{
|
||
return(RpcStatus);
|
||
}
|
||
|
||
if (ARGUMENT_PRESENT(ServerPrincName))
|
||
{
|
||
ATTEMPT_OUT_THUNK(thunkedServerPrincName, ServerPrincName);
|
||
}
|
||
|
||
return(RpcStatus);
|
||
}
|
||
|
||
|
||
RPC_STATUS RPC_ENTRY
|
||
THUNK_FN(RpcBindingSetAuthInfo)(
|
||
IN RPC_BINDING_HANDLE Binding,
|
||
IN THUNK_CHAR *ServerPrincName,
|
||
IN unsigned long AuthnLevel,
|
||
IN unsigned long AuthnSvc,
|
||
IN RPC_AUTH_IDENTITY_HANDLE AuthIdentity, OPTIONAL
|
||
IN unsigned long AuthzSvc
|
||
)
|
||
{
|
||
|
||
|
||
return ( THUNK_FN(RpcBindingSetAuthInfoEx)(
|
||
Binding,
|
||
ServerPrincName,
|
||
AuthnLevel,
|
||
AuthnSvc,
|
||
AuthIdentity,
|
||
AuthzSvc,
|
||
0
|
||
) );
|
||
|
||
}
|
||
|
||
|
||
|
||
RPC_STATUS RPC_ENTRY
|
||
THUNK_FN(RpcBindingSetAuthInfoEx) (
|
||
IN RPC_BINDING_HANDLE Binding,
|
||
IN THUNK_CHAR *ServerPrincName,
|
||
IN unsigned long AuthnLevel,
|
||
IN unsigned long AuthnSvc,
|
||
IN RPC_AUTH_IDENTITY_HANDLE AuthIdentity, OPTIONAL
|
||
IN unsigned long AuthzSvc,
|
||
IN RPC_SECURITY_QOS * SecurityQOS
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine is the ansi thunk for RpcBindingSetAuthInfoW.
|
||
|
||
Return Value:
|
||
|
||
RPC_S_OUT_OF_MEMORY - We will return this value if we do not have
|
||
enough memory to convert the ansi server principal name into
|
||
a unicode string.
|
||
|
||
--*/
|
||
{
|
||
USES_CONVERSION;
|
||
CHeapInThunk thunkedServerPrincName;
|
||
RPC_STATUS RpcStatus;
|
||
RPC_HTTP_TRANSPORT_CREDENTIALS_A *HttpCredentials;
|
||
ULONG AdditionalTransportCredentialsType;
|
||
RPC_SECURITY_QOS_V2_W SecurityQOS2;
|
||
RPC_SECURITY_QOS_V2_W *SecurityQOSToUse;
|
||
|
||
ATTEMPT_HEAP_IN_THUNK(thunkedServerPrincName, ServerPrincName);
|
||
|
||
if (SecurityQOS)
|
||
{
|
||
if (SecurityQOS->Version == RPC_C_SECURITY_QOS_VERSION_1)
|
||
{
|
||
RpcpMemoryCopy(&SecurityQOS2, SecurityQOS, sizeof(RPC_SECURITY_QOS));
|
||
SecurityQOS2.AdditionalSecurityInfoType = 0;
|
||
SecurityQOS2.u.HttpCredentials = NULL;
|
||
}
|
||
else
|
||
{
|
||
RpcpMemoryCopy(&SecurityQOS2, SecurityQOS, sizeof(RPC_SECURITY_QOS_V2_A));
|
||
AdditionalTransportCredentialsType = ((RPC_SECURITY_QOS_V2 *)SecurityQOS)->AdditionalSecurityInfoType;
|
||
HttpCredentials = ((RPC_SECURITY_QOS_V2_A *)SecurityQOS)->u.HttpCredentials;
|
||
|
||
if (AdditionalTransportCredentialsType != RPC_C_AUTHN_INFO_TYPE_HTTP)
|
||
{
|
||
if (AdditionalTransportCredentialsType != 0)
|
||
return(RPC_S_INVALID_ARG);
|
||
|
||
if (HttpCredentials != NULL)
|
||
return(RPC_S_INVALID_ARG);
|
||
}
|
||
else if (HttpCredentials == NULL)
|
||
return(RPC_S_INVALID_ARG);
|
||
else
|
||
{
|
||
if (HttpCredentials->TransportCredentials)
|
||
{
|
||
if (HttpCredentials->TransportCredentials->User)
|
||
{
|
||
if (RpcpStringLengthA((const char *)HttpCredentials->TransportCredentials->User)
|
||
!= HttpCredentials->TransportCredentials->UserLength)
|
||
{
|
||
return(RPC_S_INVALID_ARG);
|
||
}
|
||
}
|
||
else if (HttpCredentials->TransportCredentials->UserLength)
|
||
return(RPC_S_INVALID_ARG);
|
||
|
||
if (HttpCredentials->TransportCredentials->Domain)
|
||
{
|
||
if (RpcpStringLengthA((const char *)HttpCredentials->TransportCredentials->Domain)
|
||
!= HttpCredentials->TransportCredentials->DomainLength)
|
||
{
|
||
return(RPC_S_INVALID_ARG);
|
||
}
|
||
}
|
||
else if (HttpCredentials->TransportCredentials->DomainLength)
|
||
return(RPC_S_INVALID_ARG);
|
||
|
||
if (HttpCredentials->TransportCredentials->Password)
|
||
{
|
||
if (RpcpStringLengthA((const char *)HttpCredentials->TransportCredentials->Password)
|
||
!= HttpCredentials->TransportCredentials->PasswordLength)
|
||
{
|
||
return(RPC_S_INVALID_ARG);
|
||
}
|
||
}
|
||
else if (HttpCredentials->TransportCredentials->PasswordLength)
|
||
return(RPC_S_INVALID_ARG);
|
||
|
||
if (HttpCredentials->TransportCredentials->Flags != SEC_WINNT_AUTH_IDENTITY_ANSI)
|
||
return(RPC_S_INVALID_ARG);
|
||
}
|
||
|
||
// if you don't want to authenticate against anyone, you can't authenticate
|
||
if (HttpCredentials->AuthenticationTarget == 0)
|
||
return(RPC_S_INVALID_ARG);
|
||
|
||
// if you don't support any method of authentication, you can't authenticate
|
||
if (HttpCredentials->NumberOfAuthnSchemes == 0)
|
||
return(RPC_S_INVALID_ARG);
|
||
|
||
// if you don't support any method of authentication, you can't authenticate
|
||
if (HttpCredentials->AuthnSchemes == NULL)
|
||
return(RPC_S_INVALID_ARG);
|
||
|
||
SecurityQOS2.u.HttpCredentials = ConvertToUnicodeHttpTransportCredentials (
|
||
HttpCredentials);
|
||
|
||
if (SecurityQOS2.u.HttpCredentials == NULL)
|
||
return RPC_S_OUT_OF_MEMORY;
|
||
}
|
||
}
|
||
SecurityQOSToUse = &SecurityQOS2;
|
||
}
|
||
else
|
||
{
|
||
SecurityQOSToUse = NULL;
|
||
}
|
||
|
||
RpcStatus = RpcBindingSetAuthInfoEx(Binding, thunkedServerPrincName,
|
||
AuthnLevel, AuthnSvc, AuthIdentity, AuthzSvc, (RPC_SECURITY_QOS *)SecurityQOSToUse);
|
||
|
||
if (SecurityQOSToUse && (SecurityQOS2.AdditionalSecurityInfoType == RPC_C_AUTHN_INFO_TYPE_HTTP))
|
||
{
|
||
// free the converted credentials
|
||
WipeOutAuthIdentity(SecurityQOS2.u.HttpCredentials->TransportCredentials);
|
||
FreeHttpTransportCredentials(SecurityQOS2.u.HttpCredentials);
|
||
}
|
||
|
||
return(RpcStatus);
|
||
}
|
||
|
||
|
||
RPC_STATUS RPC_ENTRY
|
||
THUNK_FN(RpcMgmtInqServerPrincName) (
|
||
IN RPC_BINDING_HANDLE Binding,
|
||
IN unsigned long AuthnSvc,
|
||
OUT THUNK_CHAR **ServerPrincName
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine is the ansi thunk for RpcMgmtInqServerPrincNameW.
|
||
|
||
Return Value:
|
||
|
||
RPC_S_OUT_OF_MEMORY - We will return this value if we do not have
|
||
enough memory to convert the unicode server principal name into
|
||
an ansi string.
|
||
|
||
--*/
|
||
{
|
||
RPC_STATUS RpcStatus;
|
||
USES_CONVERSION;
|
||
COutDelThunk thunkedServerPrincName;
|
||
|
||
RpcStatus = RpcMgmtInqServerPrincName(Binding, AuthnSvc, thunkedServerPrincName);
|
||
if ( RpcStatus != RPC_S_OK )
|
||
{
|
||
return(RpcStatus);
|
||
}
|
||
|
||
ATTEMPT_OUT_THUNK(thunkedServerPrincName, ServerPrincName);
|
||
return(RPC_S_OK);
|
||
}
|
||
|
||
RPCRTAPI
|
||
RPC_STATUS
|
||
RPC_ENTRY
|
||
THUNK_FN(RpcCertGeneratePrincipalName)(
|
||
PCCERT_CONTEXT Context,
|
||
DWORD Flags,
|
||
OUT THUNK_CHAR **pBuffer
|
||
)
|
||
{
|
||
USES_CONVERSION;
|
||
COutDelThunk thunkedServerPrincName;
|
||
|
||
RPC_STATUS Status = RpcCertGeneratePrincipalName( Context,
|
||
Flags,
|
||
thunkedServerPrincName
|
||
);
|
||
if (Status != RPC_S_OK)
|
||
{
|
||
return Status;
|
||
}
|
||
|
||
|
||
ATTEMPT_OUT_THUNK(thunkedServerPrincName, pBuffer);
|
||
|
||
return Status;
|
||
}
|