windows-nt/Source/XPSP1/NT/ds/netapi/svcdlls/srvsvc/server/internal.c
2020-09-26 16:20:57 +08:00

222 lines
5.7 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
Copyright (c) 1992 Microsoft Corporation
Module Name:
Internal.c
Abstract:
This module contains "internal" APIs exported by the server service.
--*/
#include "srvsvcp.h"
#include <debugfmt.h>
#include <tstr.h>
#include <lmerr.h>
NET_API_STATUS NET_API_FUNCTION
I_NetrServerSetServiceBitsEx (
IN LPTSTR ServerName,
IN LPTSTR EmulatedServerName OPTIONAL,
IN LPTSTR TransportName OPTIONAL,
IN DWORD ServiceBitsOfInterest,
IN DWORD ServiceBits,
IN DWORD UpdateImmediately
)
/*++
Routine Description:
This routine sets the value of the Server Type as sent in server
announcement messages. It is an internal API used only by the
service controller.
Arguments:
ServerName - Used by RPC to direct the call. This API may only be
issued locally. This is enforced by the client stub.
EmulatedServerName - server name being emulated on this computer
TransportName - parameter optionally giving specific transport for which
to set the bits
ServiceBitsOfInterest - bit mask indicating significant 'ServiceBits'
ServiceBits - Bits (preassigned to various components by Microsoft)
indicating which services are active. This field is not
interpreted by the server service.
Return Value:
NET_API_STATUS - NO_ERROR or ERROR_NOT_SUPPORTED.
--*/
{
BOOL changed = FALSE;
PNAME_LIST_ENTRY Service;
PTRANSPORT_LIST_ENTRY transport;
DWORD newBits;
NET_API_STATUS error;
CHAR serverNameBuf[ MAX_PATH ];
PCHAR emulatedName;
ULONG namelen;
ServerName; // avoid compiler warnings
if( SsData.SsInitialized ) {
error = SsCheckAccess(
&SsConfigInfoSecurityObject,
SRVSVC_CONFIG_INFO_SET
);
if ( error != NO_ERROR ) {
return ERROR_ACCESS_DENIED;
}
}
if( ARGUMENT_PRESENT( EmulatedServerName ) ) {
UNICODE_STRING name;
RtlInitUnicodeString( &name, EmulatedServerName );
error = ConvertStringToTransportAddress( &name, serverNameBuf, &namelen );
if( error != NERR_Success ) {
return error;
}
emulatedName = serverNameBuf;
} else {
emulatedName = SsData.SsServerTransportAddress;
namelen = SsData.SsServerTransportAddressLength;
}
//
// Don't let bits that are controlled by the server be set.
//
ServiceBitsOfInterest &= ~SERVER_TYPE_INTERNAL_BITS;
ServiceBits &= ServiceBitsOfInterest;
//
// Make the modifications under control of the service resource.
//
(VOID)RtlAcquireResourceExclusive( &SsData.SsServerInfoResource, TRUE );
if( SsData.SsServerNameList == NULL && !ARGUMENT_PRESENT( TransportName ) ) {
//
// We have not bound to any transports yet.
// Remember the setting which is being asked for so we can use it later
//
SsData.ServiceBits &= ~ServiceBitsOfInterest;
SsData.ServiceBits |= ServiceBits;
RtlReleaseResource( &SsData.SsServerInfoResource );
return NO_ERROR;
}
//
// Find the entry for the server name of interest
//
for( Service = SsData.SsServerNameList; Service != NULL; Service = Service->Next ) {
if( Service->TransportAddressLength != namelen ) {
continue;
}
if( RtlEqualMemory( emulatedName, Service->TransportAddress, namelen ) ) {
break;
}
}
if( Service == NULL ) {
RtlReleaseResource( &SsData.SsServerInfoResource );
return NERR_NetNameNotFound;
}
//
// Apply any saved ServiceBits
//
if( SsData.ServiceBits != 0 && Service->PrimaryName ) {
Service->ServiceBits = SsData.ServiceBits;
SsData.ServiceBits = 0;
}
if( ARGUMENT_PRESENT( TransportName ) ) {
//
// Transport name specified. Set the bits for that transport only.
//
for( transport = Service->Transports; transport != NULL; transport = transport->Next ) {
if( !STRCMPI( TransportName, transport->TransportName ) ) {
//
// This is the transport of interest!
//
if( (transport->ServiceBits & ServiceBitsOfInterest) != ServiceBits ) {
transport->ServiceBits &= ~ServiceBitsOfInterest;
transport->ServiceBits |= ServiceBits;
changed = TRUE;
}
break;
}
}
if( transport == NULL ) {
//
// The requested transport was not found.
//
RtlReleaseResource( &SsData.SsServerInfoResource );
return ERROR_PATH_NOT_FOUND;
}
} else {
//
// No transport name specified. Change the bits for the whole server
//
if( ( Service->ServiceBits & ServiceBitsOfInterest ) != ServiceBits ) {
Service->ServiceBits &= ~ServiceBitsOfInterest;
Service->ServiceBits |= ServiceBits;
changed = TRUE;
}
}
RtlReleaseResource( &SsData.SsServerInfoResource );
if ( changed ) {
SsSetExportedServerType( NULL, TRUE, (BOOL)UpdateImmediately );
}
return NO_ERROR;
} // I_NetrServerSetServiceBits
NET_API_STATUS NET_API_FUNCTION
I_NetrServerSetServiceBits (
IN LPTSTR ServerName,
IN LPTSTR TransportName OPTIONAL,
IN DWORD ServiceBits,
IN DWORD UpdateImmediately
)
{
return I_NetrServerSetServiceBitsEx (
ServerName,
NULL,
TransportName,
0xFFFFFFFF, // All bits are of interest (just overlay the old bits)
ServiceBits,
UpdateImmediately
);
}