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.
952 lines
26 KiB
952 lines
26 KiB
/*++
|
|
|
|
Copyright (c) 1995 Microsoft Corporation
|
|
|
|
Module Name :
|
|
|
|
rpcutil.c
|
|
|
|
Abstract:
|
|
|
|
This module defines functions that may help to replace the rpc util
|
|
functions from rpcutil.lib
|
|
|
|
Author:
|
|
|
|
Murali R. Krishnan ( MuraliK ) 15-Sept-1995
|
|
|
|
Environment:
|
|
Win32 User Mode
|
|
|
|
Project:
|
|
|
|
Common Code for Internet Services
|
|
|
|
Functions Exported:
|
|
|
|
MIDL_user_allocate()
|
|
MIDL_user_free()
|
|
RpcBindHandleForServer()
|
|
RpcBindHandleFree()
|
|
|
|
Revision History:
|
|
|
|
Murali R. Krishnan (MuraliK) 21-Dec-1995 Support TcpIp binding & free.
|
|
Murali R. Krishnan (MuraliK) 20-Feb-1996 Support Lpc binding & free.
|
|
|
|
--*/
|
|
|
|
|
|
/************************************************************
|
|
* Include Headers
|
|
************************************************************/
|
|
|
|
# include <windows.h>
|
|
# include <rpc.h>
|
|
|
|
# include "apiutil.h"
|
|
|
|
# if DBG
|
|
|
|
# include <stdio.h>
|
|
# include <stdlib.h>
|
|
|
|
# define DBGPRINTF(s) { CHAR rgchBuff[1024]; \
|
|
sprintf s ; \
|
|
OutputDebugStringA( rgchBuff); \
|
|
}
|
|
# define DBG_CONTEXT ( rgchBuff)
|
|
|
|
|
|
# else // DBG
|
|
|
|
|
|
# define DBGPRINTF(s) /* nothing */
|
|
# define DBG_CONTEXT /* nothing */
|
|
|
|
# endif // DBG
|
|
|
|
#define ISRPC_CLIENT_OVER_TCPIP 0x00000001
|
|
#define ISRPC_CLIENT_OVER_NP 0x00000002
|
|
#define ISRPC_CLIENT_OVER_SPX 0x00000004
|
|
#define ISRPC_CLIENT_OVER_LPC 0x00000008
|
|
|
|
// # define MAX_COMPUTERNAME_LENGTH (255)
|
|
|
|
|
|
/************************************************************
|
|
* Functions
|
|
************************************************************/
|
|
|
|
|
|
PVOID
|
|
MIDL_user_allocate(IN size_t size)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
MIDL memory allocation.
|
|
|
|
Arguments:
|
|
|
|
size : Memory size requested.
|
|
|
|
Return Value:
|
|
|
|
Pointer to the allocated memory block.
|
|
|
|
--*/
|
|
{
|
|
PVOID pvBlob;
|
|
|
|
pvBlob = LocalAlloc( LPTR, size);
|
|
|
|
return( pvBlob );
|
|
|
|
} // MIDL_user_allocate()
|
|
|
|
|
|
|
|
|
|
VOID
|
|
MIDL_user_free(IN PVOID pvBlob)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
MIDL memory free .
|
|
|
|
Arguments:
|
|
|
|
pvBlob : Pointer to a memory block that is freed.
|
|
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
{
|
|
LocalFree( pvBlob);
|
|
|
|
return;
|
|
} // MIDL_user_free()
|
|
|
|
|
|
|
|
|
|
RPC_STATUS
|
|
RpcBindHandleOverNamedPipe( OUT handle_t * pBindingHandle,
|
|
IN LPWSTR pwszServerName,
|
|
IN LPWSTR pwszEndpoint,
|
|
IN LPWSTR pwszOptions,
|
|
IN LPWSTR pwszInterfaceName
|
|
)
|
|
/*++
|
|
This function uses the parameters supplied and generates a named pipe
|
|
binding handle for RPC.
|
|
|
|
Arguments:
|
|
pBindingHandle pointer to location which will contain binding handle
|
|
on successful return
|
|
pwszServerName pointer to string containing the name of the server
|
|
to which, this function will obtain a binding.
|
|
pwszEndpoint pointer to string containing the Named Pipe Endpoint
|
|
pwszOptions pointer to string containing any additional options for
|
|
binding.
|
|
|
|
|
|
Returns:
|
|
RPC_STATUS - RPC_S_OK on success
|
|
Also on success, the binding handle is stored in pBindingHandle.
|
|
It should freed after usage, using the RpcBindingFree() function.
|
|
|
|
--*/
|
|
{
|
|
RPC_STATUS rpcStatus;
|
|
LPWSTR pwszBinding = NULL;
|
|
|
|
if ( pBindingHandle != NULL) {
|
|
|
|
*pBindingHandle = NULL; // init the value
|
|
}
|
|
|
|
//
|
|
// Compose the binding string for named pipe binding
|
|
//
|
|
|
|
rpcStatus = RpcStringBindingComposeW(0, // ObjUuid
|
|
L"ncacn_np", // prot seq: named pipe
|
|
pwszServerName, // NetworkAddr
|
|
pwszEndpoint, // Endpoint
|
|
pwszOptions, // Options
|
|
&pwszBinding); // StringBinding
|
|
|
|
if ( rpcStatus == RPC_S_OK ) {
|
|
|
|
//
|
|
// establish the binding handle using string binding.
|
|
//
|
|
|
|
rpcStatus = RpcBindingFromStringBindingW(pwszBinding,
|
|
pBindingHandle );
|
|
}
|
|
|
|
if ( rpcStatus == RPC_S_OK) {
|
|
|
|
//
|
|
// set up the security information
|
|
//
|
|
|
|
rpcStatus =
|
|
RpcBindingSetAuthInfoW(*pBindingHandle,
|
|
pwszInterfaceName, // pszPrincipalName
|
|
RPC_C_AUTHN_LEVEL_PKT_PRIVACY,
|
|
RPC_C_AUTHN_WINNT,
|
|
NULL, // AuthnIdentity
|
|
0 // AuthzSvc
|
|
);
|
|
DBGPRINTF( (DBG_CONTEXT,
|
|
"RpcBindingSetAuthInfo(%S(Interface=%S), %p)"
|
|
" return %d.\n",
|
|
pwszBinding,
|
|
pwszInterfaceName,
|
|
*pBindingHandle,
|
|
rpcStatus
|
|
)
|
|
);
|
|
|
|
}
|
|
|
|
|
|
//
|
|
// Cleanup and return back.
|
|
//
|
|
|
|
if ( pwszBinding != NULL) {
|
|
RpcStringFreeW(&pwszBinding);
|
|
}
|
|
|
|
if ( rpcStatus != RPC_S_OK) {
|
|
|
|
if ( pBindingHandle != NULL && *pBindingHandle != NULL) {
|
|
|
|
// RPC should have freed the binding handle.
|
|
// We will free it now.
|
|
RpcBindingFree(*pBindingHandle);
|
|
*pBindingHandle = NULL;
|
|
}
|
|
}
|
|
|
|
return (rpcStatus);
|
|
|
|
} // RpcBindHandleOverNamedPipe()
|
|
|
|
RPC_STATUS
|
|
RpcBindHandleOverLpc( OUT handle_t * pBindingHandle,
|
|
IN LPWSTR pwszEndpoint,
|
|
IN LPWSTR pwszOptions,
|
|
IN LPWSTR pwszInterfaceName
|
|
)
|
|
/*++
|
|
This function uses the parameters supplied and generates a lpc
|
|
binding handle for RPC.
|
|
|
|
Arguments:
|
|
pBindingHandle pointer to location which will contain binding handle
|
|
on successful return
|
|
pwszEndpoint pointer to string containing the lpc Endpoint
|
|
pwszOptions pointer to string containing any additional options for
|
|
binding.
|
|
|
|
|
|
Returns:
|
|
RPC_STATUS - RPC_S_OK on success
|
|
Also on success, the binding handle is stored in pBindingHandle.
|
|
It should freed after usage, using the RpcBindingFree() function.
|
|
|
|
--*/
|
|
{
|
|
RPC_STATUS rpcStatus;
|
|
LPWSTR pwszBinding = NULL;
|
|
|
|
if ( pBindingHandle != NULL) {
|
|
|
|
*pBindingHandle = NULL; // init the value
|
|
}
|
|
|
|
//
|
|
// Compose the binding string for named pipe binding
|
|
//
|
|
|
|
rpcStatus = RpcStringBindingComposeW(0, // ObjUuid
|
|
L"ncalrpc", // prot seq: lpc
|
|
NULL, // NetworkAddr
|
|
pwszEndpoint, // Endpoint
|
|
pwszOptions, // Options
|
|
&pwszBinding); // StringBinding
|
|
|
|
if ( rpcStatus == RPC_S_OK ) {
|
|
|
|
//
|
|
// establish the binding handle using string binding.
|
|
//
|
|
|
|
rpcStatus = RpcBindingFromStringBindingW(pwszBinding,
|
|
pBindingHandle );
|
|
}
|
|
|
|
if ( rpcStatus == RPC_S_OK) {
|
|
|
|
//
|
|
// set up the security information
|
|
//
|
|
|
|
rpcStatus =
|
|
RpcBindingSetAuthInfoW(*pBindingHandle,
|
|
pwszInterfaceName, // pszPrincipalName
|
|
RPC_C_AUTHN_LEVEL_PKT_PRIVACY,
|
|
RPC_C_AUTHN_WINNT,
|
|
NULL, // AuthnIdentity
|
|
0 // AuthzSvc
|
|
);
|
|
DBGPRINTF( (DBG_CONTEXT,
|
|
"RpcBindingSetAuthInfo(%S(Interface=%S), %p)"
|
|
" return %d.\n",
|
|
pwszBinding,
|
|
pwszInterfaceName,
|
|
*pBindingHandle,
|
|
rpcStatus
|
|
)
|
|
);
|
|
|
|
}
|
|
|
|
|
|
//
|
|
// Cleanup and return back.
|
|
//
|
|
|
|
if ( pwszBinding != NULL) {
|
|
RpcStringFreeW(&pwszBinding);
|
|
}
|
|
|
|
if ( rpcStatus != RPC_S_OK) {
|
|
|
|
if ( pBindingHandle != NULL && *pBindingHandle != NULL) {
|
|
|
|
// RPC should have freed the binding handle.
|
|
// We will free it now.
|
|
RpcBindingFree(*pBindingHandle);
|
|
*pBindingHandle = NULL;
|
|
}
|
|
}
|
|
|
|
return (rpcStatus);
|
|
|
|
} // RpcBindHandleOverLpc()
|
|
|
|
|
|
|
|
|
|
#ifndef CHICAGO
|
|
|
|
//
|
|
// If changes are made to the NT version, check out the windows 95
|
|
// version located right after this routine and see if the change
|
|
// needs to be propagated there too.
|
|
//
|
|
|
|
RPC_STATUS
|
|
RpcBindHandleOverTcpIp( OUT handle_t * pBindingHandle,
|
|
IN LPWSTR pwszServerName,
|
|
IN LPWSTR pwszInterfaceName
|
|
)
|
|
/*++
|
|
|
|
NT Version
|
|
|
|
This function uses the parameters supplied and generates a dynamic end point
|
|
binding handle for RPC over TCP/IP.
|
|
|
|
Arguments:
|
|
pBindingHandle pointer to location which will contain binding handle
|
|
on successful return
|
|
pwszServerName pointer to string containing the name of the server
|
|
to which, this function will obtain a binding.
|
|
pwszInterfaceName pointer to string containing the interface name
|
|
|
|
Returns:
|
|
RPC_STATUS - RPC_S_OK on success
|
|
Also on success, the binding handle is stored in pBindingHandle.
|
|
It should freed after usage, using the RpcBindingFree() function.
|
|
|
|
--*/
|
|
{
|
|
RPC_STATUS rpcStatus;
|
|
LPWSTR pwszBinding = NULL;
|
|
|
|
if ( pBindingHandle != NULL) {
|
|
|
|
*pBindingHandle = NULL; // init the value
|
|
}
|
|
|
|
//
|
|
// Compose the binding string for named pipe binding
|
|
//
|
|
|
|
rpcStatus = RpcStringBindingComposeW(0, // ObjUuid
|
|
L"ncacn_ip_tcp", // tcpip seq
|
|
pwszServerName, // NetworkAddr
|
|
NULL, // Endpoint
|
|
L"", // Options
|
|
&pwszBinding); // StringBinding
|
|
|
|
DBGPRINTF( (DBG_CONTEXT, "\nRpcStringBindingComposeW(%S, %S) return %S."
|
|
" Error = %ld\n",
|
|
L"ncacn_ip_tcp",
|
|
pwszServerName,
|
|
pwszBinding,
|
|
rpcStatus)
|
|
);
|
|
|
|
if ( rpcStatus == RPC_S_OK ) {
|
|
|
|
//
|
|
// establish the binding handle using string binding.
|
|
//
|
|
|
|
rpcStatus = RpcBindingFromStringBindingW(pwszBinding,
|
|
pBindingHandle );
|
|
|
|
DBGPRINTF( (DBG_CONTEXT,
|
|
"RpcBindingFromStringBindingW(%S) return %d."
|
|
"Binding=%p\n",
|
|
pwszBinding,
|
|
rpcStatus,
|
|
*pBindingHandle)
|
|
);
|
|
}
|
|
|
|
if ( rpcStatus == RPC_S_OK) {
|
|
|
|
//
|
|
// set up the security information
|
|
//
|
|
|
|
rpcStatus =
|
|
RpcBindingSetAuthInfoW(*pBindingHandle,
|
|
pwszInterfaceName, // pszPrincipalName
|
|
RPC_C_AUTHN_LEVEL_PKT_PRIVACY,
|
|
RPC_C_AUTHN_WINNT,
|
|
NULL, // AuthnIdentity
|
|
0 // AuthzSvc
|
|
);
|
|
DBGPRINTF( (DBG_CONTEXT,
|
|
"RpcBindingSetAuthInfo(%S(Interface=%S), %p)"
|
|
" return %d.\n",
|
|
pwszBinding,
|
|
pwszInterfaceName,
|
|
*pBindingHandle,
|
|
rpcStatus
|
|
)
|
|
);
|
|
|
|
}
|
|
|
|
//
|
|
// Cleanup and return back.
|
|
//
|
|
|
|
if ( pwszBinding != NULL) {
|
|
|
|
DWORD rpcStatus1 = RpcStringFreeW(&pwszBinding);
|
|
DBGPRINTF( (DBG_CONTEXT, "RpcStringFreeW() returns %d.",
|
|
rpcStatus1)
|
|
);
|
|
|
|
}
|
|
|
|
if ( rpcStatus != RPC_S_OK) {
|
|
|
|
if ( pBindingHandle != NULL && *pBindingHandle != NULL) {
|
|
|
|
// RPC should have freed the binding handle.
|
|
// We will free it now.
|
|
DWORD rpcStatus1 = RpcBindingFree(*pBindingHandle);
|
|
DBGPRINTF( (DBG_CONTEXT, "RpcBindingFree() returns %d.\n",
|
|
rpcStatus1)
|
|
);
|
|
*pBindingHandle = NULL;
|
|
}
|
|
}
|
|
|
|
return (rpcStatus);
|
|
|
|
} // RpcBindHandleOverTcpIp()
|
|
|
|
#else // CHICAGO
|
|
|
|
|
|
|
|
RPC_STATUS
|
|
RpcBindHandleOverTcpIp( OUT handle_t * pBindingHandle,
|
|
IN LPWSTR pwszServerName,
|
|
IN LPWSTR pwszInterfaceName
|
|
)
|
|
/*++
|
|
|
|
Windows 95 version
|
|
|
|
This function uses the parameters supplied and generates a dynamic end point
|
|
binding handle for RPC over TCP/IP.
|
|
|
|
Arguments:
|
|
pBindingHandle pointer to location which will contain binding handle
|
|
on successful return
|
|
pwszServerName pointer to string containing the name of the server
|
|
to which, this function will obtain a binding.
|
|
pwszInterfaceName pointer to string containing the interface name
|
|
|
|
Returns:
|
|
RPC_STATUS - RPC_S_OK on success
|
|
Also on success, the binding handle is stored in pBindingHandle.
|
|
It should freed after usage, using the RpcBindingFree() function.
|
|
|
|
--*/
|
|
{
|
|
RPC_STATUS rpcStatus;
|
|
LPSTR pszBindingA = NULL;
|
|
CHAR szServerA[MAX_PATH];
|
|
CHAR szInterfaceA[MAX_PATH];
|
|
int cch;
|
|
|
|
if ( pBindingHandle != NULL) {
|
|
|
|
*pBindingHandle = NULL; // init the value
|
|
}
|
|
|
|
*szServerA = '0';
|
|
|
|
if (pwszServerName)
|
|
cch = WideCharToMultiByte(CP_ACP,
|
|
0,
|
|
pwszServerName,
|
|
-1,
|
|
szServerA,
|
|
sizeof(szServerA)/sizeof(CHAR),
|
|
NULL,NULL
|
|
);
|
|
|
|
*szInterfaceA = '0';
|
|
|
|
if(pwszInterfaceName)
|
|
cch = WideCharToMultiByte(CP_ACP,
|
|
0,
|
|
pwszInterfaceName,
|
|
-1,
|
|
szInterfaceA,
|
|
sizeof(szInterfaceA)/sizeof(CHAR),
|
|
NULL,NULL
|
|
);
|
|
|
|
|
|
//
|
|
// Compose the binding string for named pipe binding
|
|
//
|
|
|
|
rpcStatus = RpcStringBindingCompose(0, // ObjUuid
|
|
"ncacn_ip_tcp", // tcpip seq
|
|
szServerA, // NetworkAddr
|
|
NULL, // Endpoint
|
|
NULL, //L"", // Options
|
|
&pszBindingA); // StringBinding
|
|
|
|
DBGPRINTF( (DBG_CONTEXT, "\nRpcStringBindingCompose(%s, %s) return %s."
|
|
" Error = %ld\n",
|
|
"ncacn_ip_tcp",
|
|
szServerA,
|
|
pszBindingA,
|
|
rpcStatus)
|
|
);
|
|
|
|
if ( rpcStatus == RPC_S_OK ) {
|
|
|
|
//
|
|
// establish the binding handle using string binding.
|
|
//
|
|
|
|
rpcStatus = RpcBindingFromStringBinding(pszBindingA,
|
|
pBindingHandle );
|
|
|
|
DBGPRINTF( (DBG_CONTEXT,
|
|
"RpcBindingFromStringBinding(%s) return %d."
|
|
"Binding=%08x\n",
|
|
pszBindingA,
|
|
rpcStatus,
|
|
*pBindingHandle)
|
|
);
|
|
}
|
|
|
|
if ( rpcStatus == RPC_S_OK) {
|
|
|
|
//
|
|
// set up the security information
|
|
//
|
|
|
|
rpcStatus =
|
|
RpcBindingSetAuthInfo(*pBindingHandle,
|
|
szInterfaceA, // pszPrincipalName
|
|
RPC_C_AUTHN_LEVEL_PKT_PRIVACY,
|
|
RPC_C_AUTHN_WINNT,
|
|
NULL, // AuthnIdentity
|
|
0 // AuthzSvc
|
|
);
|
|
DBGPRINTF( (DBG_CONTEXT,
|
|
"RpcBindingSetAuthInfo(%s(Interface=%s), %08x)"
|
|
" return %d.\n",
|
|
pszBindingA,
|
|
szInterfaceA,
|
|
*pBindingHandle,
|
|
rpcStatus
|
|
)
|
|
);
|
|
|
|
}
|
|
|
|
//
|
|
// Cleanup and return back.
|
|
//
|
|
|
|
if ( pszBindingA != NULL) {
|
|
|
|
DWORD rpcStatus1 = RpcStringFree(&pszBindingA);
|
|
DBGPRINTF( (DBG_CONTEXT, "RpcStringFreeW() returns %d.",
|
|
rpcStatus1)
|
|
);
|
|
|
|
}
|
|
|
|
if ( rpcStatus != RPC_S_OK) {
|
|
|
|
if ( pBindingHandle != NULL && *pBindingHandle != NULL) {
|
|
|
|
// RPC should have freed the binding handle.
|
|
// We will free it now.
|
|
DWORD rpcStatus1 = RpcBindingFree(*pBindingHandle);
|
|
DBGPRINTF( (DBG_CONTEXT, "RpcBindingFree() returns %d.\n",
|
|
rpcStatus1)
|
|
);
|
|
*pBindingHandle = NULL;
|
|
}
|
|
}
|
|
|
|
return (rpcStatus);
|
|
|
|
} // RpcBindHandleOverTcpIp()
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef CHICAGO
|
|
DWORD
|
|
RpcuFindProtocolToUse( IN LPCWSTR pwszServerName)
|
|
/*++
|
|
Given the server name this funciton determines the protocol
|
|
to use for RPC binding.
|
|
|
|
The transport used is determined dynamically based on following rules.
|
|
|
|
If server name is NULL or 127.0.0.1 or same as local computer name
|
|
then use the LPC.
|
|
|
|
If server name starts with a leading "\\" (double slash),
|
|
then attempt RPC binding over NamedPipe.
|
|
|
|
If server name does not start with leading "\\",
|
|
then attempt RPC binding over TCPIP.
|
|
|
|
If TCPIP binding fails, then this function tries binding over NamedPipe.
|
|
|
|
|
|
Argument:
|
|
pwszServerName - pointer to string containing the name of the server
|
|
|
|
|
|
Returns:
|
|
DWORD containing the type of protocol to use.
|
|
|
|
--*/
|
|
{
|
|
static WCHAR g_wchLocalMachineName[ MAX_COMPUTERNAME_LENGTH + 1];
|
|
BOOL fLeadingSlashes;
|
|
DWORD dwBindProtocol = ISRPC_CLIENT_OVER_NP;
|
|
BOOL fLocalMachine;
|
|
|
|
if ( pwszServerName == NULL ||
|
|
_wcsicmp( L"127.0.0.1", pwszServerName) == 0) {
|
|
|
|
|
|
return (ISRPC_CLIENT_OVER_LPC);
|
|
}
|
|
|
|
if ( g_wchLocalMachineName[0] == L'\0') {
|
|
|
|
DWORD cchComputerNameLen = MAX_COMPUTERNAME_LENGTH;
|
|
|
|
//
|
|
// Obtain the local computer name
|
|
//
|
|
|
|
if (!GetComputerNameW( g_wchLocalMachineName,
|
|
&cchComputerNameLen)
|
|
) {
|
|
|
|
*g_wchLocalMachineName = L'\0';
|
|
}
|
|
}
|
|
|
|
fLeadingSlashes = ((*pwszServerName == L'\\') &&
|
|
(*(pwszServerName+1) == L'\\')
|
|
);
|
|
|
|
|
|
//
|
|
// Check to see if machine name matches local computer name
|
|
// if so, use LPC
|
|
//
|
|
|
|
fLocalMachine = !_wcsicmp( g_wchLocalMachineName,
|
|
((fLeadingSlashes) ?
|
|
(pwszServerName + 2) : pwszServerName)
|
|
);
|
|
|
|
if ( fLocalMachine) {
|
|
|
|
return (ISRPC_CLIENT_OVER_LPC);
|
|
}
|
|
|
|
if ( !fLeadingSlashes) {
|
|
|
|
DWORD nDots;
|
|
LPCWSTR pszName;
|
|
|
|
//
|
|
// Check if the name has dotted decimal name.
|
|
// If so then suggest TCP binding.
|
|
//
|
|
|
|
for( nDots = 0, pszName = pwszServerName;
|
|
((pszName = wcschr( pszName, L'.' )) != NULL);
|
|
nDots++, pszName++)
|
|
;
|
|
|
|
if ( nDots == 3) {
|
|
|
|
//
|
|
// if the string has 3 DOTs exactly then this string must represent
|
|
// an IpAddress.
|
|
//
|
|
|
|
return(ISRPC_CLIENT_OVER_TCPIP);
|
|
}
|
|
}
|
|
|
|
|
|
return ( ISRPC_CLIENT_OVER_NP);
|
|
} // RpcuFindProtocolToUse()
|
|
#endif
|
|
|
|
|
|
|
|
RPC_STATUS
|
|
RpcBindHandleForServer( OUT handle_t * pBindingHandle,
|
|
IN LPWSTR pwszServerName,
|
|
IN LPWSTR pwszInterfaceName,
|
|
IN LPWSTR pwszOptions
|
|
)
|
|
/*++
|
|
This function uses the parameters supplied and generates a binding
|
|
handle for RPC.
|
|
|
|
|
|
It is assumed that binding over named pipe uses static end point
|
|
with the interface name and options as provided.
|
|
|
|
Arguments:
|
|
pBindingHandle pointer to location which will contain binding handle
|
|
on successful return
|
|
pwszServerName pointer to string containing the name of the server
|
|
to which, this function will obtain a binding.
|
|
pwszInterfaceName pointer to string containing the interface name
|
|
pwszOptions pointer to string containing any additional options for
|
|
binding.
|
|
|
|
Returns:
|
|
RPC_STATUS - RPC_S_OK on success
|
|
Also on success, the binding handle is stored in pBindingHandle.
|
|
It should freed after usage, using the RpcBindingFree() function.
|
|
|
|
--*/
|
|
{
|
|
RPC_STATUS rpcStatus = RPC_S_SERVER_UNAVAILABLE;
|
|
LPWSTR pwszBinding = NULL;
|
|
DWORD dwBindProtocol = 0;
|
|
|
|
|
|
if ( pBindingHandle != NULL) {
|
|
|
|
*pBindingHandle = NULL; // init the value
|
|
}
|
|
|
|
#ifndef CHICAGO
|
|
dwBindProtocol = RpcuFindProtocolToUse( pwszServerName);
|
|
#else
|
|
dwBindProtocol = ISRPC_CLIENT_OVER_TCPIP;
|
|
#endif
|
|
|
|
switch ( dwBindProtocol) {
|
|
|
|
case ISRPC_CLIENT_OVER_LPC:
|
|
{
|
|
|
|
WCHAR rgchLpc[1024];
|
|
|
|
//
|
|
// generate a LPC end point name from the interface name.
|
|
// the End point = <InterfaceName>_LPC
|
|
//
|
|
|
|
if ( lstrlenW( pwszInterfaceName) >=
|
|
( sizeof(rgchLpc)/sizeof(WCHAR) - 6)) {
|
|
|
|
SetLastError( ERROR_INVALID_PARAMETER);
|
|
return ( ERROR_INVALID_PARAMETER);
|
|
}
|
|
|
|
lstrcpynW( rgchLpc, pwszInterfaceName, sizeof(rgchLpc)/sizeof(WCHAR) - 4);
|
|
lstrcatW( rgchLpc, L"_LPC");
|
|
|
|
//
|
|
// Attempt binding over static LPC.
|
|
//
|
|
|
|
rpcStatus = RpcBindHandleOverLpc( pBindingHandle,
|
|
rgchLpc,
|
|
pwszOptions,
|
|
pwszInterfaceName
|
|
);
|
|
|
|
DBGPRINTF(( DBG_CONTEXT,
|
|
" RpcBindingOverLpc(%S) returns %d."
|
|
" Handle = %p\n",
|
|
pwszServerName, rpcStatus, *pBindingHandle));
|
|
|
|
break;
|
|
}
|
|
|
|
case ISRPC_CLIENT_OVER_TCPIP:
|
|
|
|
// # ifdef RPC_BIND_OVER_TCP
|
|
|
|
//
|
|
// Attempt binding over TCPIP using Dynamic Endpoint.
|
|
//
|
|
|
|
rpcStatus = RpcBindHandleOverTcpIp( pBindingHandle,
|
|
pwszServerName,
|
|
pwszInterfaceName);
|
|
|
|
DBGPRINTF(( DBG_CONTEXT,
|
|
" RpcBindingOverTcpIp(%S) returns %d. Handle = %p\n",
|
|
pwszServerName, rpcStatus, *pBindingHandle));
|
|
|
|
if ( rpcStatus == RPC_S_OK) {
|
|
|
|
break; // done with RPC binding over TCP
|
|
}
|
|
|
|
// Fall Through
|
|
|
|
// # endif // RPC_BIND_OVER_TCP
|
|
|
|
case ISRPC_CLIENT_OVER_NP:
|
|
{
|
|
WCHAR rgchNp[1024];
|
|
|
|
//
|
|
// generate a NamedPipe end point name from the interface name.
|
|
// the End point = \PIPE\<InterfaceName>
|
|
//
|
|
|
|
lstrcpyW( rgchNp, L"\\PIPE\\");
|
|
if ( lstrlenW( pwszInterfaceName) >=
|
|
( sizeof(rgchNp)/sizeof(WCHAR) - 10)) {
|
|
|
|
SetLastError( ERROR_INVALID_PARAMETER);
|
|
return ( ERROR_INVALID_PARAMETER);
|
|
}
|
|
|
|
lstrcatW( rgchNp, pwszInterfaceName);
|
|
|
|
//
|
|
// Attempt binding over static NamedPipe.
|
|
//
|
|
|
|
rpcStatus = RpcBindHandleOverNamedPipe( pBindingHandle,
|
|
pwszServerName,
|
|
rgchNp,
|
|
pwszOptions,
|
|
pwszInterfaceName
|
|
);
|
|
|
|
DBGPRINTF(( DBG_CONTEXT,
|
|
" RpcBindingOverNamedPipe(%S) returns %d."
|
|
" Handle = %p\n",
|
|
pwszServerName, rpcStatus, *pBindingHandle));
|
|
break;
|
|
}
|
|
|
|
default:
|
|
break;
|
|
|
|
} // switch()
|
|
|
|
return ( rpcStatus);
|
|
|
|
} // RpcBindHandleForServer()
|
|
|
|
|
|
|
|
|
|
|
|
RPC_STATUS
|
|
RpcBindHandleFree(IN OUT handle_t * pBindingHandle)
|
|
/*++
|
|
|
|
Description:
|
|
|
|
This function frees up the binding handle allocated using
|
|
RpcBindHandleForServer(). It uses RPC Binding Free routing to do this.
|
|
This function acts just as a thunk so that the alloc/free of RPC contexts
|
|
are consolidated within this module.
|
|
|
|
Arguments:
|
|
pBindingHandle pointer to RPC binding handle that needs to be freed.
|
|
|
|
|
|
Returns:
|
|
RPC_STATUS - containig the RPC status. RPC_S_OK for success.
|
|
|
|
--*/
|
|
{
|
|
|
|
return ( RpcBindingFree( pBindingHandle));
|
|
|
|
} // RpcBindHandleFree()
|
|
|
|
/************************ End of File ***********************/
|
|
|
|
|
|
|
|
|