432 lines
10 KiB
C++
432 lines
10 KiB
C++
|
/*++
|
|||
|
|
|||
|
Copyright (C) Microsoft Corporation, 1992 - 1999
|
|||
|
|
|||
|
Module Name:
|
|||
|
|
|||
|
nsisvr.cxx
|
|||
|
|
|||
|
Abstract:
|
|||
|
|
|||
|
This is the server side NSI service support layer. These are wrappers
|
|||
|
which call the name service provider.
|
|||
|
|
|||
|
Author:
|
|||
|
|
|||
|
Steven Zeck (stevez) 03/04/92
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
#include <nsi.h>
|
|||
|
|
|||
|
#include <memory.h>
|
|||
|
#include <string.h>
|
|||
|
#include <stdio.h>
|
|||
|
|
|||
|
RPC_STATUS RPC_ENTRY
|
|||
|
RpcNsBindingExportW(
|
|||
|
IN unsigned long EntryNameSyntax,
|
|||
|
IN unsigned short * EntryName,
|
|||
|
IN RPC_IF_HANDLE RpcIfHandle, OPTIONAL
|
|||
|
IN RPC_BINDING_VECTOR * BindingVector, OPTIONAL
|
|||
|
IN UUID_VECTOR * ObjectVector OPTIONAL
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Place a server interface and objects in the name service data base.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
EntryNameSyntax - This value describes the type/format of the EntryName.
|
|||
|
|
|||
|
EntryName - Name that this export will be stored in. This is just a
|
|||
|
token that is passed on the the Name Server.
|
|||
|
|
|||
|
RpcIfHandle - The interface that is being exported.
|
|||
|
|
|||
|
BindingVector - A list of StringBindings to export that are associated
|
|||
|
with this interface.
|
|||
|
|
|||
|
ObjectVector - A list of objects that are associated with this
|
|||
|
interface and Entry Name
|
|||
|
|
|||
|
Returns:
|
|||
|
|
|||
|
Bind(), RpcBindingToStringBinding(), nsi_binding_export()
|
|||
|
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
RPC_STATUS status;
|
|||
|
UNSIGNED16 NsiStatus;
|
|||
|
NSI_SERVER_BINDING_VECTOR_T *NsiVector = 0;
|
|||
|
WIDE_STRING *StringBindingW;
|
|||
|
RT_CHAR * StringBinding = 0;
|
|||
|
RT_CHAR * DynamicEndpoint = 0;
|
|||
|
unsigned int Index;
|
|||
|
unsigned int VectorSize = 0;
|
|||
|
NSI_INTERFACE_ID_T NilIfOnWire, __RPC_FAR *IfPtr;
|
|||
|
|
|||
|
if (RpcIfHandle == NULL)
|
|||
|
{
|
|||
|
IfPtr = &NilIfOnWire;
|
|||
|
memset(IfPtr, 0, sizeof(NSI_INTERFACE_ID_T));
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
IfPtr = (NSI_INTERFACE_ID_T __RPC_FAR *)
|
|||
|
&((PRPC_CLIENT_INTERFACE)RpcIfHandle)->InterfaceId;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
if (status = I_NsServerBindSearch())
|
|||
|
return(status);
|
|||
|
|
|||
|
if (! EntryNameSyntax)
|
|||
|
EntryNameSyntax = DefaultSyntax;
|
|||
|
|
|||
|
if (BindingVector && BindingVector->Count && RpcIfHandle)
|
|||
|
{
|
|||
|
VectorSize = (unsigned int) BindingVector->Count;
|
|||
|
|
|||
|
NsiVector = (NSI_SERVER_BINDING_VECTOR_T *) I_RpcAllocate((unsigned int) (
|
|||
|
sizeof(NSI_SERVER_BINDING_VECTOR_T) +
|
|||
|
sizeof(unsigned short *) * VectorSize));
|
|||
|
|
|||
|
if (!NsiVector)
|
|||
|
return(RPC_S_OUT_OF_MEMORY);
|
|||
|
|
|||
|
NsiVector->count = 0;
|
|||
|
}
|
|||
|
|
|||
|
// Copy the vector of binding handles into a vector of string bindinds
|
|||
|
// that are wide character.
|
|||
|
|
|||
|
for (Index = 0; Index < VectorSize; Index++)
|
|||
|
{
|
|||
|
|
|||
|
if (!BindingVector->BindingH[Index])
|
|||
|
continue;
|
|||
|
|
|||
|
// Turn the private runtime data structure into a StringBinding.
|
|||
|
#ifdef NTENV
|
|||
|
status = I_RpcBindingToStaticStringBindingW(BindingVector->BindingH[Index],
|
|||
|
&StringBinding);
|
|||
|
|
|||
|
// call to remove the dynamic part from the binding
|
|||
|
// and give the string binding.
|
|||
|
#else
|
|||
|
status = RpcBindingToStringBinding(BindingVector->BindingH[Index],
|
|||
|
&StringBinding);
|
|||
|
#endif
|
|||
|
|
|||
|
if (status)
|
|||
|
goto ErrorExit;
|
|||
|
|
|||
|
StringBindingW = new WIDE_STRING (StringBinding);
|
|||
|
|
|||
|
if (!StringBindingW || StringBindingW->OutOfMemory())
|
|||
|
{
|
|||
|
status = RPC_S_OUT_OF_MEMORY;
|
|||
|
goto ErrorExit;
|
|||
|
}
|
|||
|
|
|||
|
NsiVector->string[NsiVector->count++] = &(*StringBindingW);
|
|||
|
|
|||
|
I_RpcFree(StringBindingW); // Free memory without destuctor
|
|||
|
|
|||
|
#ifndef NTENV
|
|||
|
I_RpcFree(StringBinding); // Free the non unicode string
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
RpcTryExcept
|
|||
|
{
|
|||
|
nsi_binding_export(
|
|||
|
NsiSvrBinding,
|
|||
|
EntryNameSyntax,
|
|||
|
EntryName,
|
|||
|
IfPtr,
|
|||
|
NsiVector,
|
|||
|
(NSI_UUID_VECTOR_P_T) ObjectVector,
|
|||
|
&NsiStatus
|
|||
|
);
|
|||
|
|
|||
|
}
|
|||
|
RpcExcept(1)
|
|||
|
{
|
|||
|
NsiStatus = MapException(RpcExceptionCode());
|
|||
|
}
|
|||
|
RpcEndExcept
|
|||
|
|
|||
|
status = NsiMapStatus(NsiStatus);
|
|||
|
|
|||
|
ErrorExit:
|
|||
|
// Return memory allocated for nsi vector.
|
|||
|
|
|||
|
if (NsiVector)
|
|||
|
for (Index = 0; Index < NsiVector->count; Index++)
|
|||
|
I_RpcFree(NsiVector->string[Index]);
|
|||
|
|
|||
|
if (NsiVector)
|
|||
|
I_RpcFree(NsiVector);
|
|||
|
|
|||
|
return(NsiMapStatus(NsiStatus));
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
RPC_STATUS RPC_ENTRY
|
|||
|
RpcNsBindingUnexportW(
|
|||
|
IN unsigned long EntryNameSyntax OPTIONAL,
|
|||
|
IN unsigned short * EntryName,
|
|||
|
IN RPC_IF_HANDLE RpcIfHandle OPTIONAL,
|
|||
|
IN UUID_VECTOR * ObjectVector OPTIONAL
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Remove a server interface and objects in the name service data base.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
EntryNameSyntax - This value describes the type/format of the EntryName.
|
|||
|
|
|||
|
EntryName - Name that this export will be stored in. This is just a
|
|||
|
token that is passed on the the Name Server.
|
|||
|
|
|||
|
RpcIfHandle - The interface that is being unexported.
|
|||
|
|
|||
|
ObjectVector - A list of objects that are associated with this
|
|||
|
interface and Entry Name
|
|||
|
|
|||
|
Returns:
|
|||
|
|
|||
|
Bind(), nsi_binding_unexport()
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
RPC_STATUS status;
|
|||
|
UNSIGNED16 NsiStatus;
|
|||
|
NSI_INTERFACE_ID_T NilIfOnWire, __RPC_FAR *IfPtr;
|
|||
|
|
|||
|
if (RpcIfHandle == NULL)
|
|||
|
{
|
|||
|
IfPtr = &NilIfOnWire;
|
|||
|
memset(IfPtr, 0, sizeof(NSI_INTERFACE_ID_T));
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
IfPtr = (NSI_INTERFACE_ID_T __RPC_FAR *)
|
|||
|
&((PRPC_CLIENT_INTERFACE)RpcIfHandle)->InterfaceId;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
if (status = I_NsServerBindSearch())
|
|||
|
return(status);
|
|||
|
|
|||
|
if (! EntryNameSyntax)
|
|||
|
EntryNameSyntax = DefaultSyntax;
|
|||
|
|
|||
|
RpcTryExcept
|
|||
|
{
|
|||
|
nsi_binding_unexport(NsiSvrBinding, EntryNameSyntax, EntryName,
|
|||
|
IfPtr, (NSI_UUID_VECTOR_P_T) ObjectVector,
|
|||
|
&NsiStatus);
|
|||
|
}
|
|||
|
RpcExcept(1)
|
|||
|
{
|
|||
|
NsiStatus = MapException(RpcExceptionCode());
|
|||
|
}
|
|||
|
RpcEndExcept
|
|||
|
|
|||
|
return(NsiMapStatus(NsiStatus));
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
RPC_STATUS RPC_ENTRY
|
|||
|
RpcNsBindingExportA(
|
|||
|
IN unsigned long EntryNameSyntax,
|
|||
|
IN unsigned char * EntryName,
|
|||
|
IN RPC_IF_HANDLE RpcIfHandle,
|
|||
|
IN RPC_BINDING_VECTOR * BindingVector, OPTIONAL
|
|||
|
IN UUID_VECTOR * ObjectVector OPTIONAL
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This is an ASCII wrapper to the UNICODE version of the API. It
|
|||
|
converts all char * -> short * strings and calls the UNICODE version.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
WIDE_STRING EntryNameW(EntryName);
|
|||
|
|
|||
|
if (EntryNameW.OutOfMemory())
|
|||
|
return(RPC_S_OUT_OF_MEMORY);
|
|||
|
|
|||
|
return(RpcNsBindingExportW(EntryNameSyntax, &EntryNameW,
|
|||
|
RpcIfHandle, BindingVector, ObjectVector));
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
RPC_STATUS RPC_ENTRY
|
|||
|
RpcNsBindingUnexportA(
|
|||
|
IN unsigned long EntryNameSyntax,
|
|||
|
IN unsigned char * EntryName,
|
|||
|
IN RPC_IF_HANDLE RpcIfHandle,
|
|||
|
IN UUID_VECTOR * ObjectVector OPTIONAL
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This is an ASCII wrapper to the UNICODE version of the API. It
|
|||
|
converts all char * -> short * strings and calls the UNICODE version.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
WIDE_STRING EntryNameW(EntryName);
|
|||
|
|
|||
|
if (EntryNameW.OutOfMemory())
|
|||
|
return(RPC_S_OUT_OF_MEMORY);
|
|||
|
|
|||
|
return(RpcNsBindingUnexportW(EntryNameSyntax, &EntryNameW,
|
|||
|
RpcIfHandle, ObjectVector));
|
|||
|
}
|
|||
|
|
|||
|
#ifdef NTENV
|
|||
|
|
|||
|
/*
|
|||
|
Function:
|
|||
|
The Binding Vector corresponding to this Server is discovered
|
|||
|
using InqBindings, And is cached along with the EntryName and RpcIfHandle
|
|||
|
in the same Process.
|
|||
|
|
|||
|
When a PnP event occurs resulting in addition/deletion of the bindings
|
|||
|
Corresponding changes are made to the Name Service database. (added or deleted)
|
|||
|
|
|||
|
Notice that this can not be called from a process that is not a server. The
|
|||
|
Exports have to be done from the server itself if it has to be PnP aware
|
|||
|
|
|||
|
*/
|
|||
|
|
|||
|
RPC_STATUS RPC_ENTRY
|
|||
|
RpcNsBindingExportPnPW(
|
|||
|
IN unsigned long EntryNameSyntax,
|
|||
|
IN unsigned short * EntryName,
|
|||
|
IN RPC_IF_HANDLE RpcIfHandle, OPTIONAL
|
|||
|
IN UUID_VECTOR * ObjectVector OPTIONAL
|
|||
|
)
|
|||
|
|
|||
|
{
|
|||
|
RPC_STATUS status = RPC_S_OK;
|
|||
|
RPC_BINDING_VECTOR *BindingVec = NULL;
|
|||
|
|
|||
|
status = RpcServerInqBindings(&BindingVec);
|
|||
|
// InqBindings to get the binding vector
|
|||
|
|
|||
|
if (status != RPC_S_OK)
|
|||
|
return status;
|
|||
|
|
|||
|
|
|||
|
status = RpcNsBindingExportW(EntryNameSyntax, EntryName,
|
|||
|
RpcIfHandle, BindingVec,
|
|||
|
ObjectVector
|
|||
|
);
|
|||
|
if (status != RPC_S_OK)
|
|||
|
return status;
|
|||
|
|
|||
|
// only if this is valid, other invalid cases will all be caught before
|
|||
|
|
|||
|
if (RpcIfHandle)
|
|||
|
status = I_RpcNsInterfaceExported(EntryNameSyntax, EntryName,
|
|||
|
(RPC_SERVER_INTERFACE *)RpcIfHandle);
|
|||
|
|
|||
|
return status;
|
|||
|
|
|||
|
// going to cache for bindings exported to the locator
|
|||
|
// (only if the prev. export succeeded)
|
|||
|
}
|
|||
|
|
|||
|
/*
|
|||
|
Removes all the bindings corresponding to this particular server
|
|||
|
from the Name Service database. It also removes it from the cache that
|
|||
|
is maintained for the EntryName/InterfaceId combination.
|
|||
|
|
|||
|
Notice that this can not be called from a process that is not a server. The
|
|||
|
Unexports have to be done from the server itself if it has to be PnP aware
|
|||
|
|
|||
|
*/
|
|||
|
|
|||
|
RPC_STATUS RPC_ENTRY
|
|||
|
RpcNsBindingUnexportPnPW(
|
|||
|
IN unsigned long EntryNameSyntax OPTIONAL,
|
|||
|
IN unsigned short * EntryName,
|
|||
|
IN RPC_IF_HANDLE RpcIfHandle OPTIONAL,
|
|||
|
IN UUID_VECTOR * ObjectVector OPTIONAL
|
|||
|
)
|
|||
|
{
|
|||
|
RPC_STATUS status = RPC_S_OK;
|
|||
|
status = RpcNsBindingUnexportW(EntryNameSyntax, EntryName,
|
|||
|
RpcIfHandle, ObjectVector);
|
|||
|
|
|||
|
if (status != RPC_S_OK)
|
|||
|
return status;
|
|||
|
|
|||
|
if (RpcIfHandle)
|
|||
|
status = I_RpcNsInterfaceUnexported(EntryNameSyntax, EntryName,
|
|||
|
(RPC_SERVER_INTERFACE *)RpcIfHandle);
|
|||
|
// once it has got removed, remove it from the cache as well.
|
|||
|
|
|||
|
return status;
|
|||
|
}
|
|||
|
|
|||
|
RPC_STATUS RPC_ENTRY
|
|||
|
RpcNsBindingExportPnPA(
|
|||
|
IN unsigned long EntryNameSyntax,
|
|||
|
IN unsigned char * EntryName,
|
|||
|
IN RPC_IF_HANDLE RpcIfHandle, OPTIONAL
|
|||
|
IN UUID_VECTOR * ObjectVector OPTIONAL
|
|||
|
)
|
|||
|
|
|||
|
{
|
|||
|
WIDE_STRING EntryNameW(EntryName);
|
|||
|
|
|||
|
if (EntryNameW.OutOfMemory())
|
|||
|
return(RPC_S_OUT_OF_MEMORY);
|
|||
|
|
|||
|
return(RpcNsBindingExportPnPW(EntryNameSyntax, &EntryNameW,
|
|||
|
RpcIfHandle, ObjectVector));
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
RPC_STATUS RPC_ENTRY
|
|||
|
RpcNsBindingUnexportPnPA(
|
|||
|
IN unsigned long EntryNameSyntax OPTIONAL,
|
|||
|
IN unsigned char * EntryName,
|
|||
|
IN RPC_IF_HANDLE RpcIfHandle OPTIONAL,
|
|||
|
IN UUID_VECTOR * ObjectVector OPTIONAL
|
|||
|
)
|
|||
|
{
|
|||
|
WIDE_STRING EntryNameW(EntryName);
|
|||
|
|
|||
|
if (EntryNameW.OutOfMemory())
|
|||
|
return(RPC_S_OUT_OF_MEMORY);
|
|||
|
|
|||
|
return(RpcNsBindingUnexportPnPW(EntryNameSyntax, &EntryNameW,
|
|||
|
RpcIfHandle, ObjectVector));
|
|||
|
}
|
|||
|
#endif
|